2016-01-22 80 views
6

这个模板ctor隐藏移动ctor吗?具有通用参考的模板构造函数是否隐藏移动构造函数?

class A { 
    public: 
     template<typename T> 
     A(T &&t); 

     // move would be as this: 
     /* 
      A(A &&a); 
     */ 
}; 

那么在这种情况下应该如何实现移动ctor呢?应该使用默认语法A (A &&)还是模板专业化?

+1

看来,至少在海湾合作委员会,移动时不考虑模板ctor:http://coliru.stacked-crooked.com/a/3c995d34b40fb4bc如果这是根据标准的情况下,那么你可以实现移动ctor通常的方式。 – user2079303

回答

3

根据标准(草案)

[class.copy]

3甲非模板构造用于类X是移动构造函数,如果它的第一个参数是X型&的&,const X & &,易失性X & &或常量易失性X & &,或者没有其他参数或者其他所有参数ameter具有默认参数(8.3.6)。 [例如:Y :: Y(Y & &)是一个移动构造函数。

只有非模板构造函数可以移动构造函数。同样适用于复制构造函数。因此会生成隐式移动构造函数。

以通常的方式实现移动构造函数。专业化将不起作用,因为重载解析首选隐式非模板移动构造函数。

但是,如果参数类型与const T&不完全匹配,则模板引用将胜出重载解析。这很容易发生,可以从Praveen的例子中看出。

+1

**同样适用于复制构造函数**。 'a a2 {a1};'调用'template'而不是'copy constructor'。为什么? http://ideone.com/JAfjLy – Praveen

+3

@Praveen因为'a1'不是'const'。转发引用非常贪婪。 – TartanLlama

5

接受的答案不正确。虽然确实如此:template <typename T> A(T &&t) { }不是移动构造函数,但您已经知道这一点。编译器将隐式声明在这种情况下和正常负载分辨率的移动构造函数会按预期工作:

A a{2}; // calls template 
A b = std::move(a); // calls move 
A c{a}; // calls template 

没有什么被搬进c排除a是,即使该模板的构造是不是一个“移动”构造函数。

+3

你怎么知道提问者知道模板不算作移动构造函数?它在接受的答案中说,没有移动构造函数是隐式声明的? (或_“接受的答案是不正确的”_是指什么?) – nwp