简体   繁体   English

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

[英]C++ template copy constructor on template class

I have a template class that has a template copy constructor.我有一个模板类,它有一个模板复制构造函数。 The problem is when I instantiate this class using another instance of this class with the same template type, my template copy constructor is not called.问题是当我使用具有相同模板类型的此类的另一个实例实例化此类时,不会调用我的模板复制构造函数。 Why doesn't it match?为什么不匹配?

Here is the code snippet:这是代码片段:

#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;
}

The output is输出是

default constructor

But if I explicitly write the default copy constructor (by uncommenting it), then the output becomes但是如果我显式地编写了默认的复制构造函数(通过取消注释),那么输出就变成了

default constructor
copy constructor

I really don't get it.我真的不明白。 I tested it with my local compiler (Clang 500.2.79) and with this one (GCC 4.9.2) and got the same result.我用我的本地编译器(Clang 500.2.79)和这个(GCC 4.9.2)测试了它并得到了相同的结果。

A copy constructor is of the form X(X& ) or (X const&) and will be provided for you by the compiler if you didn't declare one yourself (or a few other conditions which are not relevant here).复制构造函数的形式为X(X& )(X const&) ,如果您没有自己声明(或其他一些与此无关的条件),编译器将为您提供。 You didn't, so implicitly we have the following set of candidates:你没有,所以我们隐含地有以下一组候选人:

MyTemplateClass(const MyTemplateClass&);
template <typename U> MyTemplateClass(const MyTemplateClass<U>&);

Both are viable for两者都是可行的

MyTemplateClass<int> instance2(instance);

Both take the same exact arguments.两者都采用相同的确切参数。 The issue isn't that your copy constructor template doesn't match .问题不在于您的复制构造函数模板不匹配 The issue is that the implicit copy constructor is not a function template, and non-templates are preferred to template specializations when it comes to overload resolution.问题在于隐式复制构造函数不是函数模板,在重载解析方面,非模板比模板特化更受欢迎。 From [over.match.best], omitting the unrelated bullet points:从 [over.match.best],省略不相关的要点:

Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICS i (F1) is not a worse conversion sequence than ICS i (F2), and then鉴于这些定义,如果对于所有参数 i,ICS i (F1) 不是比 ICS i (F2) 更差的转换序列,那么一个可行函数 F1 被定义为比另一个可行函数 F2 更好的函数,然后
— [...] — [...]
— F1 is not a function template specialization and F2 is a function template specialization, or, if not that, — F1 不是函数模板特化,F2 是函数模板特化,或者,如果不是,
— [...] — [...]

That's why it calls your implicit (and then, your explicit) copy constructor over your constructor template.这就是为什么它在构造函数模板上调用隐式(然后是显式)复制构造函数。

When you do not have a copy constructor in you code, the compiler will implicitly generate it.当您的代码中没有复制构造函数时,编译器将隐式生成它。 Therefore when this line is executed:因此,当执行此行时:

MyTemplateClass<int> instance2(instance);

A copy constructor is being executed, though obviously not yours.正在执行的拷贝构造函数,但显然不是你的。 I think that templating has nothing to do with it.我认为模板与它无关。

Read more about it here: Implicitly-defined copy constructor在此处阅读更多相关信息: 隐式定义的复制构造函数

I think REACHUS is right.我认为 REACHUS 是对的。 The compiler is generating a default copy-constructor (as it would with a non-template class too) and preferring this over your template as it's more specialised.编译器正在生成一个默认的复制构造函数(就像使用非模板类一样)并且比模板更喜欢它,因为它更专业。

You should make your "normal" copy-constructor private, or better, use the C++11 'deleted' keyword to mark the function as unusable.您应该将“普通”复制构造函数设为私有,或者更好的是,使用 C++11 'deleted' 关键字将该函数标记为不可用。

However, this doesn't compile.但是,这不会编译。 Sorry, I wasn't able to test it at the time.抱歉,我当时无法测试。

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

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