2017-10-26 10 views
3

私は値を持つテンプレートの特殊化を実行しようとしていましたが、一方はbool、もう一方はenumクラスです。私は1日コンパイラと戦っていたが、 "あふれた関数へのあいまいな呼び出し"エラーを克服できなかった。 すなわちコードは醜いとかなり長いが、ここで簡単なテストケースである:MSVCコンパイラでenumクラスを使用して "オーバーロードされた関数へのあいまいな呼び出し"

#include <iostream> 

enum class Foo { Bar }; 
enum class Waldo { Fred }; 

template<Foo ARG, typename... _Types> 
inline bool DOIT(_Types&&... _Args) 
{ 
    return true; 
} 

template<Waldo ARG, typename... _Types> 
inline bool DOIT(_Types&&... _Args) 
{ 
    return false; 
} 

int main() 
{ 
    std::cout << DOIT<Foo::Bar>() << std::endl; 
    std::cout << DOIT<Waldo::Fred>() << std::endl; 
    return 0; 
} 

両方打ち鳴らす3.8とgcc 4.8.3は、標準のC++ 11に設定された状態で、滞りなくこれをコンパイルし、しかしMSVCは私にC2668エラーメッセージを発し続けます。

AFAIK enumクラスの1つの理由は、暗黙的な変換を避けることでしたが、わかりません。これはコンパイラのエラーですか、標準の欠陥ですか?

+0

スコープ付き列挙型の使用を考慮すると、間違いなくMSVCのしくみです。 – StoryTeller

+1

Visual Studioに組み込まれているclangコンパイラには、「エラー:別の定義と同じ名前の同じ名前の定義」があります。テンプレート型ではなく、関数型の型で名前を変更した古いVC++バグを思い出させます。おそらくこの問題はまだ生きていますか? –

答えて

5

あなたが投稿したコードは、_で始まる識別子を使用した後に大文字を使用したため、診断不要の不正なプログラムです。このような識別子は、コンパイラの実装者のための標準によって予約されています。

しかし、それはあなたの問題ではありません。


標準を以下のとき gccと打ち鳴らすの両方が、それは間違って持っている間MSVCは右のそれを得たところ、私が今まで1ケースを見てきました。

これに加えて、あいまいさはここでは意味がありません。

コンパイラが破損しています。動作するはず

方法は次のとおりです。

template<Foo ARG, typename... Ts> 
inline bool DOIT(std::integral_constant<Foo, ARG>, Ts&&... args) 
{ 
    return true; 
} 
template<Waldo ARG, typename... Ts> 
inline bool DOIT(std::integral_constant<Waldo, ARG>, Ts&&... args) 
{ 
    return false; 
} 

int main() 
{ 
    std::cout << DOIT(std::integral_constant<Foo, Foo::Bar>{}) << std::endl; 
    std::cout << DOIT(std::integral_constant<Waldo, Waldo::Fred>{}) << std::endl; 
    return 0; 
} 

works on this online MSVC compiler

関連する問題