2016-08-18 24 views
7

考慮模板化的構造函數可以代表刪除的拷貝構造函數嗎?

template<typename T> 
struct Foo 
{ 
    Foo(const Foo&) = delete; 
    template <typename Y> 
    Foo(const Foo<Y>&){} 
}; 

是否模板的構造的適當實例站在了拷貝構造函數?我知道它通常不會(因爲拷貝構造函數不能是模板函數),但是在這裏我刪除了拷貝構造函數。

+4

'美孚(const的T&)'是不是一個拷貝構造函數。'美孚(常量Foo&)'會。 – aschepler

+0

對不起,我想我有模板語法不正確。現在好點了嗎? –

+1

刪除的函數仍然存在,用於重載解析。嘗試使用它只是一個錯誤。另一方面,從所有類似的類型創建拷貝必須非常不尋常,但不是來自相同類型的拷貝。 –

回答

3

不,它不能:重載分辨率總是首先考慮非模板功能,並且遇到delete d時,過載分辨率失敗,而不是考慮模板過載。

允許我介紹一下默認的構造函數到類與線

Foo() = default;

然後,考慮兩個變量

Foo<double> double_foo; 
Foo<int> int_foo; 

然後記

  1. Foo<int> bar(double_foo);允許因到模板
  2. Foo<int> bar(int_foo);不允許因delete d構造
  3. Foo<int> bar = Foo<int>();如果你已經寫Foo(const Foo&&) = default;重新推出了移動構造函數被允許。由於Foo<int> bar(Foo<int>());是前向聲明,因此您需要使用=語法。

最後,斷言「複製構造函數不能是模板函數」是不正確的。信用@LightnessRacesInOrbit:

C++ 14 12.8.2「類X A非模板構造器是一個拷貝 構造如果它的第一個參數是X型&,常量X &,易失性的 X &或const揮發性X &,並且或者有沒有其他的參數或其他 所有其他參數默認參數(8.3.6)。

+0

非常感謝,但你認爲你可以解釋你最後的筆記嗎? –

+1

谷歌「最痛苦的解析」。 – Bathsheba

4

這裏的麻煩是刪除的函數仍然參與重載解析。因此,考慮

Foo<int> a; 
Foo<int> b{a}; 

的可行功能刪除拷貝構造函數和與推導的模板參數int模板的構造。作爲非模板,刪除的拷貝構造函數獲勝。並且使用刪除的功能會使程序不合格。

因此,不能將模板構造函數實例化爲用於複製相同類型對象的複製構造函數。