2016-04-04 23 views
3
template <typename T> 
void func(){ 
    T* t = new T(); 
    t->do_something(); 
    ... 
} 

在這種情況下,編譯器如何知道typename T會在其上定義一個方法do_something()?在Java中,我們可以指定泛型類擴展的接口,但C++顯然不具有相同的語法。那麼如果我們撥打func<AClassThatDoesntHaveDoSomethingDefined>()會發生什麼?C++如何知道模板類在編譯時支持哪些方法?

+0

可能的重複:http://stackoverflow.com/q/122316/365102,http://stackoverflow.com/a/15671344/365102 –

+0

@MateenUlhaq號我不問如何在模板上添加約束。我更好奇爲什麼C++允許這樣的代碼編譯,以及在未定義被調用的函數時如何處理這種情況。 – OneZero

+1

@OneZero語言的規則是,除非實例化模板,否則很少進行檢查。然而,一旦模板被實例化 - 有足夠的信息知道存在問題,不是? –

回答

7

編譯器不知道,直到你實例化模板函數...與T。 然後它會查找是否T有這樣的方法...如果沒有,你會得到一個錯誤。

想象模板類型(如佔位符),沒有爲模板函數生成的代碼,直到它使用類型實例化爲止。所以如果你有這樣的功能,而且它從來沒有被調用過,那麼它將不會是程序集的一部分。這是templates的許多功能之一。

當您致電func<AClassThatDoesntHaveDoSomethingDefined>()時,編譯器用AClassThatDoesntHaveDoSomethingDefined代替typename T。編譯如下

void func(){ 
    AClassThatDoesntHaveDoSomethingDefined* t = new AClassThatDoesntHaveDoSomethingDefined(); 
    t->do_something(); 
    ... 
} 

通常的規則...如果沒有定義do_something(),你會得到一個錯誤:它會嘗試創建這樣的函數。

有上模板這裏多一點信息:https://isocpp.org/wiki/faq/templates

+0

@CaptainGiraffe ...謝謝。回答修改...我希望現在更好;-) – WhiZTiM

1

模板不知道nuthin'直到它們被使用。只要它們被使用,模板就會變成代碼,代替佔位符的模板參數。然後編譯這個生成的代碼,如果這些替代參數中的任何一個沒有達到這個新生成的代碼的要求,那麼你會得到一個錯誤消息。

分階段思考。

您定義以下模板

template<T> 
bool func(T val) 
{ 
    return val.getstate(); 
} 

在編譯過程中,

std::string test; 
if (func(test)) 

被發現,觸發模板。編譯器然後運行並從模板創建

bool func(std::string val) 
{ 
    return val.getstate(); 
} 

。在編譯後的某段時間,這個生成的函數將被編譯,並且發現std::string::getstate不存在,從而產生錯誤消息。

相關問題