Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSVC2015 decltype parameter type in overloaded template function

Tags:

c++

c++11

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.

like image 394
Ross Bencina Avatar asked Dec 06 '16 17:12

Ross Bencina


1 Answers

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"; }
like image 133
Violet Giraffe Avatar answered Oct 13 '22 23:10

Violet Giraffe