“模糊模板专业化”问题

时间:2010-05-15 16:36:16

标签: c++ templates gcc porting

我目前正在移植一堆以前只使用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;
}

1 个答案:

答案 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成功编译。