[英]Why isn't GCC giving me an error
對於我希望的示例,GCC並沒有給我一個錯誤:
class CannotBeCopied {
public:
CannotBeCopied(const CannotBeCopied&) = delete;
CannotBeCopied& operator=(const CannotBeCopied&) =delete;
CannotBeCopied() { }
~CannotBeCopied() { }
};
template<class T>
class FirstVector {
public:
FirstVector() {
size = 1;
data = new T[size];
}
~FirstVector() {
delete[] data;
}
FirstVector(const FirstVector& source) {
size = source.size;
data = new T[size];
for(int k=0;k!=size;k++) {
data[k] = source.data[k]; //<--I EXPECT AN ERROR HERE
}
}
private:
int size;
T* data;
};
當不使用復制構造函數時,不會發生此錯誤(也就是說,在使用復制構造函數時,確實會發生此錯誤)。
由於有了模板,我不能簡單地將copy-ctor移到代碼文件中,並且在編譯時會失敗。
我怎樣才能使它失敗?
這不是SFINAE,它應該無法實例化模板。 如果copy-ctor本身是模板方法(例如:
template<class U=T>
在上面的那一行,那就是SFINAE。
我正在使用GCC 4.8.1, -pedantic -Wall -Wextra
和-std=c++11
我希望通過以下操作使它失敗:
int main() {
FirstVector<CannotBeCopied> whatever;
}
我知道GCC只是懶惰而不必做它不需要做的工作,但是我不喜歡如果我要在代碼文件中顯式實例化此模板,則會收到錯誤消息。 有沒有辦法得到我想要的錯誤?
如果您實際上並未創建模板的實例,則無需調用復制構造函數-如果不使用,則甚至不會為CannotBeCopied
創建模板代碼。 調用復制構造函數,您將得到錯誤:
FirstVector<CannotBeCopied> a;
FirstVector<CannotBeCopied> b = a;
編輯:您還可以通過添加所有模板的成員來使用模板的顯式實例化
template class FirstVector<CannotBeCopied>;
(語言規范的第14.7.2節)
C ++中的模板只有在使用時才會實現 。 其他一切都太昂貴了。
您可能已經聽說過,C ++模板正在完善中,因此評估它們可能非常昂貴。 IIRC上有一個Fibonnaci <17>的示例,它將使編譯器計算該數字...
特別是,這意味着將消除死代碼,並且僅當您嘗試使用復制構造函數時,c ++編譯器才會失敗。
這不僅僅是海灣合作委員會懶惰的問題; 絕對禁止它按照標准執行您想要的操作。 [temp.inst] / p1、2、11:
1除非已經明確實例化了類模板專業化(14.7.2)或明確了專門化(14.7.3),否則在需要完全定義的對象類型的上下文中引用該專業化時,將隱式實例化該類模板專業化。類類型的完整性會影響程序的語義。 [...]類模板專業化的隱式實例化導致聲明的隱式實例化,而不是類成員函數的定義,默認參數或異常規范的隱式實例化。[...]
2除非已明確實例化或顯式實例化了類模板或成員模板的成員,否則在需要成員定義存在的上下文中引用專門化時,將隱式實例化成員的專門化。 [...]
11實現不得隱式實例化不需要實例化的類模板的函數模板,變量模板,成員模板,非虛擬成員函數,成員類或靜態數據成員。
這使您可以使用例如std::vector
的僅移動類型。 它們的副本構造函數將不會編譯,但是只要您不使用它們, std::vector<std::unique_ptr<T>>
就是完全有效的。
要強制它失敗,您可以在FirstVector
內部使用static_assert
:
static_assert(std::is_copy_constructible<T>::value, "T must be copy constructible");
但是請注意,這僅檢查副本構造函數的聲明是否可訪問且未被刪除,而不檢查副本構造函數的主體將進行編譯,這意味着它將錯誤地報告std::vector<std::unique_ptr<T>>
是可復制構造的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.