模板类上的c ++模板复制构造函数

Jai*_*ard 9 c++ templates copy-constructor

我有一个模板类,它有一个模板复制构造函数.问题是当我使用具有相同模板类型的此类的另一个实例来实例化此类时,我的模板复制构造函数未被调用.为什么不匹配?这是代码片段:

#include <iostream>

template <typename T>
class MyTemplateClass
{
    public:
        MyTemplateClass()
        {
            std::cout << "default constructor" << std::endl;
        }

        /*
        MyTemplateClass(const MyTemplateClass<T>& other)
        {
            std::cout << "copy constructor" << std::endl;
        }
        */

        template <typename U>
        MyTemplateClass(const MyTemplateClass<U>& other)
        {
            std::cout << "template copy constructor" << std::endl;
        }
};

int main()
{
    MyTemplateClass<int> instance;
    MyTemplateClass<int> instance2(instance);
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

输出是

default constructor
Run Code Online (Sandbox Code Playgroud)

但是如果我显式地编写默认的复制构造函数(通过取消注释它),那么输出就变成了

default constructor
copy constructor
Run Code Online (Sandbox Code Playgroud)

我真的不明白.我用我的本地编译器(clang-500.2.79)和这个(gcc 4.9.2)测试了它并得到了相同的结果.

Bar*_*rry 8

副本构造函数的形式为X(X& )(X const&),并会被编译器提供你,如果你没有自己(或这里不涉及其他一些条件)申报一个.你没有,所以隐含地我们有以下一组候选人:

MyTemplateClass(const MyTemplateClass&);
template <typename U> MyTemplateClass(const MyTemplateClass<U>&);
Run Code Online (Sandbox Code Playgroud)

两者都可行

MyTemplateClass<int> instance2(instance);
Run Code Online (Sandbox Code Playgroud)

两者都采用相同的确切论点.问题不在于您的复制构造函数模板不匹配.问题是隐式复制构造函数不是函数模板,并且在涉及重载解析时,非模板优先于模板特化.从[over.match.best]中,省略不相关的项目符号点:

给定这些定义,可行函数F1被定义为比另一个可行函数F2更好的函数,如果对于所有自变量i,ICS i(F1)不是比ICS i(F2)更差的转换序列,然后
- [.. .]
- F1不是功能模板专业化,F2是功能模板专业化,或者,如果不是,
- [...]

这就是为什么它会在构造函数模板上调用隐式(然后是你的显式)复制构造函数.

  • @REACHUS直接答案是因为这是规则(添加了标准报价)。一般规则是-选择最具体的功能。非模板比模板更具体。 (2认同)