2016-12-06 63 views
6

下面的程序是否符合C++ 11?如果是这样,你知道触发它的特定MSVC错误吗?和/或可能的解决方法?MSVC2015 decltype参数类型重载模板函数

#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然后它工作,但在实践中,这些类型都太复杂重现,我不希望有他们的别名。

+0

编译很好用gcc/clang,而且我也没有看到不兼容C++ 11的东西。 – Jarod42

回答

4

对我的作品(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"; } 
+0

我以为MSVC正在做别名的文本替换。我很惊讶它的工作。我正在处理一些很久以前与这些“未知类型”有关的一些讨厌的bug,很高兴知道别名正在起作用。 –

+0

@GuillaumeRacicot:类型别名不被视为新的独立类型,对吧?我宁愿期望它不会自己工作,现在你已经提出来了。显然,这不是混淆编译器的类型本身,而是'decltype()'构造,并且我的修改将它放在不同的编译器_can_正确处理的上下文中。至少这是我目前的理论。 –

+0

显然这也适用:'template using wrap = T;'then wrap'decltype(aaa)>'in parameter list。 –