2011-04-29 49 views
4
#include <cstdlib> 

template<class A> struct Foo 
{ 
    template<class B> static bool Bar(); 
}; 

template<class B> template<class A> bool Foo<A>::Bar<B>() 
{ 
    return true; 
} 

int main() 
{ 
    bool b = Foo<int>::Bar<long>(); 
    b; 
} 

定義模板類的模板成員分開這導致鏈接錯誤:從宣言

main.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl Foo<int>::Bar<long>(void)" ([email protected]@[email protected]@@SA_NXZ) referenced in function main 

我需要定義類模板的聲明之外這個成員函數。換句話說,我不能這樣做:

#include <cstdlib> 
template<class A> struct Foo 
{ 
    template<class B> static bool Bar() 
    { 
     return true; 
    } 
}; 

int main() 
{ 
    bool b = Foo<int>::Bar<long>(); 
    b; 
} 

我在想什麼?我如何定義這個成員函數模板?需要什麼語法?

注意:我正在使用MSVC 2008,以防萬一。

編輯

我想的第一件事就是扭轉template<class A>template<class B>順序:

#include <cstdlib> 

template<class A> struct Foo 
{ 
    template<class B> static bool Bar(); 
}; 

template<class A> template<class B> bool Foo<A>::Bar<B>() 
{ 
    return true; 
} 

int main() 
{ 
    bool b = Foo<int>::Bar<long>(); 
    b; 
} 

這就產生了一個編譯器錯誤:

.\main.cpp(11) : error C2768: 'Foo<A>::Bar' : illegal use of explicit template arguments 

上的大括號定義爲Bar函數。

回答

3

只是顛倒了template<class B> template<class A>的順序。第二個是「內部」,並與會員聲明。見§14.5.2/ 1。

另外,正如John指出的那樣,從Bar<B>中刪除參數列表。

// "outer" template: this parameter gets substituted to create "inner" template 
template< class A > 

// "inner" template stands alone after "outer" substitution 
template< class B > 

bool 
// This will just be a class name after "outer" substitution. 
     foo<A> 
// This has usual function template syntax 
      :: Bar() { 
+0

這是我第一次嘗試。這導致了編譯器錯誤。我將編輯OP。 – 2011-04-29 21:50:56

2

這個工作對我來說:

template<class A> 
template<class B> 
bool Foo<A>::Bar() 
{ 
    return true; 
} 

在你寫兩個template符中的順序(外模板至上)。此外,如果實際上將<B>放在函數模板的名稱上,至少有一個編譯器(GCC)認爲您試圖部分專用功能Bar,這是不可能的。

+0

似乎也適合我,但是'B'會發生什麼?這太奇怪了! – 2011-04-29 21:53:30

+0

我現在明白了這個星期五!趣味有趣有趣的樂趣 – 2011-04-29 22:03:05