我正在探索 friend
的用法具有可变参数模板、完美转发和私有(private)构造函数的关键字。我觉得我错过了所有这一切的一些基本内容,因为下面的简单示例无法编译。
我要Test_Manager<Test_Class>::Process
是构造 Test_Class
类型的对象的唯一方法( Process
最终会做更多的事情,但这是一个简单的例子)。我也想要Test_Manager
能够以这种方式“管理”各种类,因此有争论 t_Symbol
对于类类型和变量 ...t_Args
处理各种构造函数。
// Test.cpp
#include <string>
template<typename t_Symbol>
struct Test_Manager
{
template<typename... t_Args>
static t_Symbol Process(const t_Args&... i_Args)
{
const t_Symbol New_Symbol(std::forward<t_Args>(i_Args)...); // error C2665
return New_Symbol;
}
};
class Test_Class
{
private:
friend Test_Manager<Test_Class>;
Test_Class() {};
Test_Class(const std::string& i_Text) : m_Text(i_Text) {};
const std::string m_Text;
};
void Test_Function()
{
std::string text = "hello_world";
Test_Class t = Test_Manager<Test_Class>::Process(text);
}
但是,在 Visual Studio 2015 Update 3 中,我收到以下错误(在上面标记的行处):error C2665: 'std::forward': none of the 2 overloads could convert all the argument types
。我在这里搞砸了什么?我觉得这应该可行。
最佳答案
What am I screwing up here?
是的,你是。在下面的代码中:
template<typename... t_Args>
static t_Symbol Process(const t_Args&... i_Args){
const t_Symbol New_Symbol(std::forward<t_Args>(i_Args)...);
...
}
上面的问题是i_Args
将有一个const
资格但你告诉 std::forward
std::forward<t_Arg>
您将发送 t_Arg
类型,不带有 const
资格。
所以,本质上,你的 std::forward<t_Args>(i_Arg)
的问题是类型 t_Args
,不带有隐式 const
,但是参数 i_Arg
,有 const
.
您应该使用std::forward
关于转发引用文献。当你这样做时,t_Arg
将隐式携带必要的 cv 限定条件,该限定条件将与 i_Arg
的 cv 限定条件相匹配。
您想将其更改为:
template<typename... t_Args>
static t_Symbol Process(t_Args&&... i_Args){
...
}
编辑,根据 Guillaume Racicot 的评论:
当您尝试将值移动到Process
时,例如:
Test_Manager<Test_Class>::Process(std::move(text));
Test_Class
的构造函数将击败std::forward
因为它仍然会按照原样进行复制。
Test_Class(const std::string& i_Text) : m_Text(i_Text) {};
但是,当构造函数定义为:
Test_Class(std::string i_Text) : m_Text(std::move(i_Text)) {};
不会进行复制,只会移动。
关于c++ - 通过模板化的友元类完美转发到私有(private)类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43035148/