Ross Bencina
Ross Bencina

Reputation: 4173

MSVC2015 decltype parameter type in overloaded template function

Is the following program compliant C++11? If so, do you know of a specific MSVC bug that triggers it? and/or a possible work-around?

#include <iostream>

struct A {};
struct B {};

constexpr A aaa = {};
constexpr B bbb = {};

template <typename T>
void foo(T, decltype(aaa)) { std::cout << "a"; }

template <typename T>
void foo(T, decltype(bbb)) { std::cout << "b"; }
// ^ C2995 'void foo(T,unknown-type)': function template has already been defined

int main()
{
    foo(0, aaa);
    foo(0, bbb);
}

If the actual types are substituted for decltype then it works, but in practice these types are too complicated to reproduce and I'd prefer not to have aliases for them.

Upvotes: 6

Views: 160

Answers (1)

Violet Giraffe
Violet Giraffe

Reputation: 33599

Works for me (VS 2015 / v140) with the following minor modification:

#include <iostream>

struct A {};
struct B {};

constexpr A aaa = {};
constexpr B bbb = {};

using A_type = decltype(aaa);
using B_type = decltype(bbb);

template <typename T>
void foo(T, A_type) { std::cout << "a"; }

template <typename T>
void foo(T, B_type) { std::cout << "b"; }

int main()
{
    foo(0, aaa);
    foo(0, bbb);
}

But this variant yields the same error (not sure what to make of it):

template <typename T>
struct TypeWrapper {
    using type = T;
};

template <typename T>
void foo(T, typename TypeWrapper<decltype(aaa)>::type) { std::cout << "a"; }

template <typename T>
void foo(T, typename TypeWrapper<decltype(bbb)>::type) { std::cout << "b"; }

Upvotes: 4

Related Questions