c++ - 通过模板化的友元类完美转发到私有(private)类构造函数

标签 c++ variadic-templates perfect-forwarding

我正在探索 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_Argcv 限定条件相匹配。

您想将其更改为:

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/

相关文章:

c++ - C/C++ 中的 long long

c++ - 将参数与其他参数一起转发给构造函数

c++ - 修改传递给该函数内部可变参数函数的参数

c++ - 可变参数模板 : choose the tuple element type that has a proper method

c++ - 使用可变参数模板进行隐式转换

c++ - 使用经典重载解析规则创建依赖于 std::invoke 的重载集类

c++ - 我无法按类型访问使用 forward_as_tuple 创建的元组中的元素

c++ - 使用 SendMessage() 多线程

c++ - Windows编程: Why do we cast lParam to CREATESTRUCT to get application state?

c++ - 模板函数返回 void