11

I believe I've found a compiler bug in MSVC++ (present up to VS 2013). I want to check that it is indeed a bug before I report it.

The following code:

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

Produces a compile error:

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>          ]

However, it looks OK to me, and compiles fine on ideone.com. Is it a bug? Should it compile cleanly?

9
  • Compiles fine on GCC 4.9.1 Commented Oct 30, 2014 at 9:59
  • Out of curiosity, would it help if you made the primary template's body legal (i.e. changed the type of ret to map<typename T::StoredType, int>)? Commented Oct 30, 2014 at 10:04
  • @Angew same here, the code i wrong since map<T, int> is not map<typename T::StoredType, int>, even more curious if it compiles on GCC :D Commented Oct 30, 2014 at 10:05
  • Apologies - I was mucking about trying to find a minimal example and obviously didn't back up far enough. It still fails with a "correct" primary template body (as you'd expect - the template isn't instantiated, so it shouldn't ever be compiled). I'll edit the question. Commented Oct 30, 2014 at 10:09
  • It also appears I commented the wrong error line. Also fixed. Commented Oct 30, 2014 at 10:10

1 Answer 1

1

What is interesting that the same thing on a class specialization works fine:

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

If the map is defined in the template then it also seems fine:

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

So the assumption about the bug seems to be possible.

Sign up to request clarification or add additional context in comments.

1 Comment

Your answer would be easier to read if you just showed the parts that you’ve changed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.