2016-12-06 61 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。 –