在模板类中使用 r 和 l 值构造函数时出错

Error when using r and l value constructors in a template class

本文关键字:构造函数 出错      更新时间:2023-10-16

我有一个这样的类模板:

template <typename T>
class MyClass
{
public:
     MyClass(const T & val);  // First
     MyClass(T&& val);        // Second
};

基本上,我希望MyClass可以从T构造,无论是右值还是左值。现在当我有类似的东西

const A& foo = ...;
MyClass<const A&> x(foo); 

我收到MyClass(const A & val)的重新定义错误。

我认为这是因为 T&& 是一个通用引用,并且由于引用折叠规则,第二个构造函数也会转换为与第一个构造函数具有相同的签名。

首先,我对错误场景的理解是否正确? 其次,我该如何解决这个问题(我想能够使用移动语义在构造 MyClass 时提供的优化)?

我认为这是因为T&&是一个普遍的参考......

不對。 在这种情况下,T&&不是通用(转发)引用。 T&& 正是对 T 的右值引用。必须推断出通用/转发参考。

。由于引用折叠规则,第二个构造函数也会转换为与第一个构造函数具有相同的签名。

这是正确的。我们的两个构造函数采用:

T const& ==> A const& const& ==> A const&
T&&      ==> A const& &&     ==> A const&

因此,重定义错误。

根据您要执行的操作,一个简单的解决方案可能是仅std::decay T

template <typename T>
class MyClass
{
    using DecT = typename std::decay<T>::type;
public:
    MyClass(const DecT& );
    MyClass(DecT&& );
};

对于您的示例,这仍将创建一个具有两个构造函数的类:一个采用const A&,另一个采用A&&