簡體   English   中英

模板類上的 C++ 模板復制構造函數

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

我有一個模板類,它有一個模板復制構造函數。 問題是當我使用具有相同模板類型的此類的另一個實例實例化此類時,不會調用我的模板復制構造函數。 為什么不匹配?

這是代碼片段:

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

輸出是

default constructor

但是如果我顯式地編寫了默認的復制構造函數(通過取消注釋),那么輸出就變成了

default constructor
copy constructor

我真的不明白。 我用我的本地編譯器(Clang 500.2.79)和這個(GCC 4.9.2)測試了它並得到了相同的結果。

復制構造函數的形式為X(X& )(X const&) ,如果您沒有自己聲明(或其他一些與此無關的條件),編譯器將為您提供。 你沒有,所以我們隱含地有以下一組候選人:

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

兩者都是可行的

MyTemplateClass<int> instance2(instance);

兩者都采用相同的確切參數。 問題不在於您的復制構造函數模板不匹配 問題在於隱式復制構造函數不是函數模板,在重載解析方面,非模板比模板特化更受歡迎。 從 [over.match.best],省略不相關的要點:

鑒於這些定義,如果對於所有參數 i,ICS i (F1) 不是比 ICS i (F2) 更差的轉換序列,那么一個可行函數 F1 被定義為比另一個可行函數 F2 更好的函數,然后
— [...]
— F1 不是函數模板特化,F2 是函數模板特化,或者,如果不是,
— [...]

這就是為什么它在構造函數模板上調用隱式(然后是顯式)復制構造函數。

當您的代碼中沒有復制構造函數時,編譯器將隱式生成它。 因此,當執行此行時:

MyTemplateClass<int> instance2(instance);

正在執行的拷貝構造函數,但顯然不是你的。 我認為模板與它無關。

在此處閱讀更多相關信息: 隱式定義的復制構造函數

我認為 REACHUS 是對的。 編譯器正在生成一個默認的復制構造函數(就像使用非模板類一樣)並且比模板更喜歡它,因為它更專業。

您應該將“普通”復制構造函數設為私有,或者更好的是,使用 C++11 'deleted' 關鍵字將該函數標記為不可用。

但是,這不會編譯。 抱歉,我當時無法測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM