繁体   English   中英

如何通过CRTP将lvalue引用传递给std :: forward?

[英]How does it pass lvalue reference to std::forward with CRTP?

我用CRTP(Curiously Reccursive Template Pattern)测试了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中传递rvalue时,gcc编译器不会给我编译错误。

如何将lvalue赋予container.add<DataClassA>(data_a)

你打电话时:

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

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

使用DataClassA作为模板参数实例化add意味着它的签名是:

void add(DataClassA&& tag) 

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

要使用完美转发,必须让编译器从参数中推导出模板参数。 基于参数的值类别有三种可能的推论( TT&T&& ),这就是std::forward如何再现参数的值类别:

container.add(data_a);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM