2011-05-06 143 views
5

考慮下面的例子:專業化模板函數

#include <iostream> 

template< int a > 
void foo(); 

int main(int argn, char* argv[]) 
{ 
    foo<1>(); 
} 

template<> 
void foo<1>() 
{ 
    std::cout<<1<<std::endl; 
} 

編譯失敗,接下來的錯誤消息:

rg.cpp:12: error: specialization of ‘void foo() [with int a = 1]’ after instantiation 

什麼款的標準解釋了這個錯誤?

PS:我知道如果我移動main前面的函數定義會使錯誤消失。

回答

10

我認爲這是未定義的行爲根據標準。工具鏈在UB的情況下可以做什麼沒有限制,產生編譯器錯誤是更友好的可能性之一。


[temp.spec],14.7p5說

對於給定的模板,一組給定的模板參數

  • 明確的實例化德網絡nition應出現在最多一次一個程序,
  • 一個明確的專業化應該至多在程序中定義一次(根據到3.2)和
  • 顯式實例化和顯式特化的聲明不應出現在 程序中,除非顯式實例化遵循顯式專用化的聲明。

實施不需要診斷違反此規則。

[temp.expl.spec] 14.7.3p6說:

如果一個模板,一個成員模板或類模板的成員明確專門然後這個特應在第一次使用的是專業化的前申報這將導致在發生這種使用的每個翻譯單元中發生隱含的實例化;不需要診斷。


你的程序違反了這些要求。

+0

+1爲第二個報價。我正在尋找那個。 – Nawaz 2011-05-06 14:32:05

+0

是的,我正在尋找14.7.3。謝謝 – 2011-05-06 14:33:41