2010-05-15 120 views
3

我目前移植已以前只被編譯與Visual Studio 2008 在這段代碼的代碼堆,有這樣的安排:「曖昧模板專業化」的問題

一般來說,有很多不同的返回類型的模板函數的特化時調用這樣的:

int i = convert<int>(szInt); 

的問題是,這些模板專門化導致「不明確的模板特殊化」。 如果除了區分這些函數特化的返回類型之外,我顯然可以使用重載,但這不是一個選項。

如何解決這個問題,而不必更改所有轉換函數被調用的地方?

更新 我添加了這兩個全部模板專業化,我第一次省略。 我很尷尬地說,我不確定第二個的動機,但第一個是由於convert函數被用於很多地方,其中字符串數據被作爲void *傳遞。 我現在無法使用GCC進行檢查,但我懷疑這可能是問題所在。

更新2 下面是完整的cpp文件,它將重現此問題。 如果你刪除了兩個「通用」函數,它將被編譯。 如果你讓他們中的任何一個留下來,就會產生不明確的模板專門化錯誤。

#include <iostream> 
#include <sstream> 

template <typename T> 
T convert(const char * s) 
{ 
    // this is a slow slow general purpose catch all, if no specialization is provided 
    std::istringstream is(s); 
    T ret; 
    is >> ret; 
    return ret; 
} 

// general purpose 1 
template <typename T, typename T2> 
T convert(T2 * s) 
{ 
    return convert<T>(static_cast<const char*>(s)); 
} 

// general purpose 2 
template <typename T, typename T2> 
T convert(T2 s) 
{ 
    return T(s); 
} 

// Type specialized 

template <> 
inline float convert<float>(const char * s) 
{ 
    return (float)atof(s); 
} 

int main(int argc, const char * sz[]) 
{ 
    return 0; 
} 
+8

代碼中必須有別的東西,你沒有在問題中顯示。上述代碼完全沒有歧義,我已經測試過它可以用g ++(i686-apple-darwin10-g ++ - 4.2.1)正確編譯。試着想出一個你看到含糊不清和編輯問題的案例。 – 2010-05-15 16:42:08

+0

如果我理解正確,這可能已經爲您完成了:http://www.boost.org/doc/libs/1_43_0/libs/conversion/lexical_cast.htm – Anycorn 2010-05-15 16:49:07

+0

是 - 迴應David Rodriguez的評論,您是否可以提供最小化重現問題的例子? – 2010-05-15 19:24:18

回答

1

顯然return convert<T>(static_cast<const char*>(s));(或別的東西,我看不到)被誘導編譯器創建的T convert(const char * s)爲T =浮動模板實例。然後,當您稍後嘗試專門化時,它會失敗,因爲模板版本已經存在。

當我在通用轉換器之前(const char*模板函數之後)移動了inline float convert<float>(const char * s)之後,我能夠用g ++ 4.2成功編譯。

+0

這個變化對我來說也很有用 - 你看到的是「你看不見的東西」 - 它是使用模板的代碼之一,它使用T = float在一個點上。 非常感謝。 – Setien 2010-06-03 06:52:44