簡體   English   中英

為什么標准不將模板構造函數視為復制構造函數?

[英]Why doesn't the standard consider a template constructor as a copy constructor?

這是復制構造函數的定義, [class.copy.ctor / 1]

如果X類的第一個參數是X&,const X&,volatile X&或const volatile X&,並且沒有其他參數或者所有其他參數都有默認參數([dcl。],則X類的非模板構造函數是一個復制構造函數。 fct.default])。

為什么標准將模板排除為復制構造函數?

在這個簡單的例子中,兩個構造函數都是復制構造函數:

struct Foo {
    Foo(const Foo &); // copy constructor
    Foo(Foo &);       // copy constructor
};

看到這個類似的例子:

struct Foo {
     Foo() = default;

     template <typename T>
     Foo(T &) {
         printf("here\n");
     }
};

int main() {
    Foo a;
    Foo b = a;
}

在此示例中,將打印here 所以我的模板構造函數似乎是一個復制構造函數,至少它表現得像一個(它在通常調用復制構造函數的上下文中調用)。

為什么文本中存在“非模板”要求?

讓模板放在一邊一秒鍾。 如果類未聲明復制構造函數,則會生成隱式默認值。 它可能被定義為已刪除,但它仍然是默認的。

成員模板不是成員函數。 成員僅在需要時才從中實例化。

那么編譯器如何才能從類定義中知道是否需要使用T = Foo 它不能。 但正是在這個問題上,它需要根據如何處理隱式默認復制構造函數(AND移動構造函數)的潛在需求做出決定。 那變得凌亂。

最簡單的方法是排除模板。 無論如何,我們總是會有一些復制構造函數,它默認會執行正確的TM ,並且會被重載解析所支持,因為它不是從模板中實例化的。

為什么文本中存在“非模板”要求?

鑒於它是不同的,復制構造函數可以是模板。 如果存在復制構造函數模板,非復制構造函數怎么可能不明確? 考慮一下:

struct Foo {
   // ctor template: clearly useful and necessary
   template <typename T>
      Foo(const T&) {}

   // copy ctor: same signature! can't work
   template <typename T>
      Foo(const T &) {}
};

此外,構造Foo從一個對象,該對象是不是一個Foo可以通過轉化或普通的結構來實現的,但是允許從一個非復制結構Foo對象改變復制的概念來復制包括轉換 但這已經可以用現有方案(轉換或非復制構造)實現。

在此示例中,將打印此處。 所以我的模板構造函數似乎是一個復制構造函數

您顯示的示例不會調用復制構造,而是調用普通的隱式構造。 如果您將構造函數模板更改為

template <typename T>
Foo(const T &) {
//  ^^^^^
    printf("here\n");
}

那么Foo b = a; 導致編譯器生成的復制構造函數被調用。 請注意,編譯器生成的copy ctor具有以下簽名:

Foo(const Foo&);

這需要增加一個const -qualifier到aFoo b = a; 您的代碼段中的原始構造函數模板Foo(T&)是更好的匹配,因為沒有添加const -qualifier。

復制構造函數的形式為X(X&)或(X const&),如果您沒有自己聲明,它將由編譯器為您提供。 如果您使用模板類,非模板可能會因此而出現問題。

假設有一個模板類,它有一個模板復制構造函數。 問題是,當您使用具有相同模板類型的此類的另一個實例來實例化該類時,將不會調用模板復制構造函數。

問題不在於您的復制構造函數模板不匹配。 問題是隱式復制構造函數不是函數模板,並且在涉及重載解析時,非模板優先於模板特化。

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

暫無
暫無

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

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