我用CRTP(好奇地递归模板模式)测试了std::forward。
但是我不能将左值传递给它。请阅读以下代码。

#include <algorithm>

struct DataClassA {};

template <typename Derived>
struct ContainerCRTP {
    template <typename Element>
    void add(Element&& tag) { }
};

struct Container : public ContainerCRTP<Container> { };

int main()
{
    DataClassA data_a;
    Container container;

    // Case 1: passing lvalue. compile error.
    container.add<DataClassA>(data_a);

    // Case 2: passing rvalue. It succeeds compiling.
    container.add<DataClassA>(std::move(data_a));
}

在案例1中传递左值时,gcc编译器给我一个编译错误,
template argument deduction/substitution failed:
cannot convert ‘data_a’ (type ‘DataClassA’) to type ‘DataClassA&&’

另一方面,当我在案例2中传递右值时,gcc编译器不会给我编译器错误。

如何给左值container.add<DataClassA>(data_a)

最佳答案

你打电话时:

container.add<DataClassA>(data_a);
//            ^^^^^^^^^^^

显式提供template参数意味着编译器不会推断出template参数(即,您不会获得转发引用行为)。

使用add作为模板参数实例化DataClassA意味着其签名为:
void add(DataClassA&& tag)

它是一个右值引用,而不是转发引用,因此左值参数不能绑定(bind)到它。

要使用完美转发,您必须让编译器从参数中推导出template参数。根据参数的值类别,有三种可能的推论(TT&T&&),这是std::forward再现参数值类别的方式:
container.add(data_a);

关于c++ - 它如何通过CRTP将左值引用传递给std::forward?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43976991/

10-11 18:06