2

我想聲明函數模板的專用,但稍後在源文件中定義它。考慮下面的例子:單獨聲明和模板函數專業化的定義:成員函數和非成員函數的不同行爲

.hpp

// approach #1 
template <typename T> const char *GetTypeName(); 
template <> const char *GetTypeName<int>(); 

// approach #2 
template <typename T> class TypeName {static const char *Get();}; 
template <> const char *TypeName<int>::Get(); 

.cpp

// approach #1 
template <> const char *GetTypeName<int>() 
{ 
    return "int" 
} 

// approach #2 
template <> const char *TypeName<int>::Get() 
{ 
    return "int" 
} 

在2012 MSVC(CTP是安裝),這兩個變種編譯罰款,但非會員變種(#1)引發鏈接錯誤(未解決的外部錯誤,等等)。這是正常的行爲嗎? MSVC的具體?編譯器錯誤?在CTP中修復?

編輯
我只使用專門的版本。它們在頭文件中聲明並在源文件中定義。這種方法適用於成員,但不適用於獨立功能。

EDIT 2
嗯......我想在家裏打造同一個快照(相同MSVC安裝,無需CTP),並將其鏈接沒有問題。看起來像當地的錯誤或安裝損壞。

+0

的專長,或者是無法解析的外部?在相同的DLL或不同的DLL中使用? – 2013-04-24 22:50:02

+0

@JamesKanze非會員專業化未解決的外部問題。我只使用專用版本。獨立的應用程序,沒有DLL。 – 2013-04-24 22:54:31

+0

而專業化實施的源文件是該項目的一部分? – 2013-04-24 23:08:49

回答

2

函數模板不是函數。完全專用的功能模板的一個功能。

由於必須定義所有(odr-used)函數,因此必須有辦法爲任意模板實例化生成定義。因此,主要功能模板的定義必須位於標題中。

header.h:

template <typename T>   // this 
const char * GetTypeName()  // is 
{        // not 
    return "foo";    // a 
}        // function 

template <> 
const char * GetTypeName<int>(); 

impl.cpp:

#include "header.h" 

template <> 
const char * GetTypeName<int>() 
{ 
    return "int"; 
} 
+0

但我打算只使用專用版本。即使在這種情況下,我也必須提供函數模板的定義嗎? – 2013-04-24 22:42:48

+0

@ShadowsInRain編號編譯器只需要爲它使用的實例化定義。如果您只使用專業版本,那麼這些是您需要的唯一定義。 – 2013-04-24 22:48:04

+0

@JamesKanze就這樣。我只使用專用版本,它們在頭文件中聲明並在源文件中定義。 – 2013-04-24 23:03:14