Тип параметра decltype MSVC2015 в перегруженной функции шаблона

соответствует ли следующая программа C++11? Если да, знаете ли вы о конкретной ошибке MSVC, которая запускает его? и / или возможный обходной путь?

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

если фактические типы заменены на decltype тогда это работает, но на практике эти типы слишком сложны для воспроизведения, и я бы предпочел не иметь псевдонимов для них.

1 ответов


Works for me (VS 2015 / v140) со следующей незначительной модификацией:

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

но этот вариант дает ту же ошибку (не уверен, что с этим делать):

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