2010-01-08 71 views
4

我有一些麻煩向前宣稱使用boost::enable_if功能:下面這段代碼給了我一個編譯器錯誤:正向宣稱使用enable_if功能:曖昧通話

// Declaration 
template <typename T> 
void foo(T t); 

// Definition 
template <typename T> 
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t) 
{ 
} 

int main() 
{ 
    foo(12); 
    return 0; 
} 

編譯時,我得到一個「曖昧致電foo「錯誤。根據enable_if的定義,當條件爲真時,'type'typedef對應於void,所以據我所知,foo的兩個簽名匹配。爲什麼編譯器認爲它們是不同的,是否有正確的方法來轉發聲明foo(最好不要重複enable_if部分)?

+0

匹配的問題,編譯器不能決定你要使用的模板。 – 2010-01-08 18:26:44

回答

3

這不僅是enable_if的問題。你得到的Visual Studio和GCC與下面的代碼相同的錯誤:

struct TypeVoid { 
    typedef void type; 
}; 

template<typename T> 
void f(); 

template<typename T> 
typename T::type f() { 
} 

int main() 
{ 
    f<TypeVoid>(); 
    return 0; 
} 

我認爲主要的問題是,返回類型(實例化之前)是一個模板函數簽名的一部分。有更多的信息here

關於你的代碼,如果該聲明是指定義,你應該同時匹配:

// Declaration  
template <typename T>  
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);  

// Definition  
template <typename T>  
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)  
{  
} 

如果聲明指的是不同的函數,編譯器將永遠無法選擇正確的一個int s,因爲它們都是有效的。但是,您可以禁用使用disable_ifINT S中的第一個:

// Other function declaration 
template <typename T> 
typename boost::disable_if<boost::is_same<T, int> >::type foo(T t); 

// Defition 
template <typename T>  
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)  
{  
} 
1

問題是聲明和定義不匹配。

解決方案是聲明應該包含完全相同的簽名和enable_if位。

#include <boost/type_traits/is_same.hpp> 
#include <boost/utility/enable_if.hpp> 

// Declaration 
template <typename T> 
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t); 

// Definition 
template <typename T> 
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t) 
{ 
} 

int main() 
{ 
    foo(12); 
    return 0; 
} 

這個編譯好的VC2008。