我目前正在移植一堆以前只使用Visual Studio 2008编译的代码。 在这段代码中,有这样的安排:
template <typename T>
T convert( const char * s )
{
// slow catch-all
std::istringstream is( s );
T ret;
is >> ret;
return ret;
}
template <typename T, typename T2>
T convert( T2 * s )
{
return convert<T>( static_cast<const char*>( s ));
}
template <typename T, typename T2>
T convert( T2 s )
{
return T( s );
}
template <>
inline int convert<int>( const char * s )
{
return (int)atoi( s );
}
通常,模板化函数有很多特殊化,具有不同的返回类型,可以这样调用:
int i = convert<int>( szInt );
问题是,这些模板专业化会导致“不明确的模板专业化”。 如果除了返回类型之外还有区别这些函数特化的东西,我显然可以使用重载,但这不是一个选项。
如何在不更改转换函数调用的所有位置的情况下解决此问题?
更新的 我添加了这两个我第一次省略的全能模板专业化。 我很尴尬地说,我不确定第二个的动机,但第一个是由于转换函数被用于许多将字符串数据作为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;
}
答案 0 :(得分:1)
显然return convert<T>( static_cast<const char*>( s ));
(或其他我看不到的东西)诱使编译器为T = float创建T convert( const char * s )
的模板实例化。然后,当您稍后尝试对其进行专门化时,它会失败,因为模板版本已经存在。
当我在通用转换器之前移动inline float convert<float>( const char * s )
时(紧接在const char*
模板函数之后),我能够使用g ++ 4.2成功编译。