开发者

"Ambiguous template specialization" problem

I'm currently porting a heap of code that has previously only been compiled with Visual Studio 2008. In this code, there's an arrangement like this:

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 );
}

Generally, there are a lot of specializations of the templated function with different return types that are invoked like this:

int i = convert<int>( szInt );

The problem is, that these template specializations result in "Ambiguous template specialization". If it was something besides the return type that differentiated these function specializations, I could obviously just use overloads, but that's not an option.

How do I solve this without having to change all the places the convert functions are called?

Update I added these two catch-all template specializations that I omitted the first time around. I am embarassed to say, I am unsure about the motivation for the second one, but the first one is due to the convert function being used a lot of places where string data is passed as a void *. I am unable to check it with GCC right now, but I suspect that these might be the problem.

Update 2 Here's the complete cpp file that will reproduce this. If you remove both of the "general purpose" functions, it will compile. If 开发者_JS百科you let either of them stay, the ambiguous template specialization error will result.

#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;
}


Apparently return convert<T>( static_cast<const char*>( s )); (or something else I can't see) is inducing the compiler to create a template instantiation of T convert( const char * s ) for T=float. Then when you try to specialize it later, it fails because the template version already exists.

When I moved the inline float convert<float>( const char * s ) before the general purpose converters (immediately after the const char* template function), I was able to compile successfully with g++ 4.2.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜