MSVC++中可能的编译器错误

Cho*_*ett 11 c++ visual-c++ compiler-bug

我相信我在MSVC++中找到了编译器错误(目前直到VS 2013).我想在报告之前检查它确实是一个错误.

以下代码:

#include <map>

using std::map;

template <typename T>
class A
{
public:
    typedef T StoredType;
};

template <typename T>
map<typename T::StoredType, int> foo()
{
    map<typename T::StoredType, int> ret;
    return ret;
}  

template<>
map<char, int> foo<A<char>>()
{
    map<char, int> ret;
    return ret;
} // Error on this line

int main(int, char**)
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产生编译错误:

1>d:\documents\visual studio 2010\projects\proj\proj\source1.cpp(24): error C2785: 'std::map<T::StoredType,int> foo(void)' and 'std::map<_Kty,_Ty> foo(void)' have different return types
1>          with
1>          [
1>              _Kty=char,
1>              _Ty=int
1>          ]
1>          d:\documents\visual studio 2010\projects\proj\proj\source1.cpp(13) : see declaration of 'foo'
1>          d:\documents\visual studio 2010\projects\proj\proj\source1.cpp(20) : see declaration of 'foo'
1>d:\documents\visual studio 2010\projects\proj\proj\source1.cpp(24): error C2912: explicit specialization; 'std::map<_Kty,_Ty> foo<A<T>>(void)' is not a specialization of a function template
1>          with
1>          [
1>              _Kty=char,
1>              _Ty=int,
1>              T=char
1>          ]
Run Code Online (Sandbox Code Playgroud)

但是,它看起来不错,并且在ideone.com上编译得很好.这是一个错误吗?它应该干净地编译吗?

Rud*_*lis 1

有趣的是,在类专业化上同样的事情工作得很好:

#include <map>

using std::map;

template <typename T>
class A
{
public:
    typedef T StoredType;
};

template <typename T>
struct Z
{
    map<typename T::StoredType, int> foo()
    {
        map<T::StoredType, int> ret;
        return ret;
    }  // Error on this line
};

template<>
struct Z<A<char>>
{
    map<char, int> foo()
    {
        map<char, int> ret;
        return ret;
    }
};

int main(int, char**)
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果地图是在模板中定义的,那么它看起来也很好:

#include <map>

using std::map;

template <typename T>
class A
{
public:
    typedef map<T, int> MapType;
};

template <typename T>
typename T::MapType foo()
{
    T::MapType ret;
    return ret;
}

template<>
map<char, int> foo<A<char>>()
{
    map<char, int> ret;
    return ret;
}

int main(int, char**)
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

因此,关于该错误的假设似乎是可能的。