2010-05-15 143 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