2017-07-18 32 views
0

私は列挙型をラップし、そのための文字列変換を提供するクラスを持っています。ここでは、テンプレートパラメータ 'fastStringConvert'を導入しました。このテンプレートパラメータは、SFINAE(ここでは、how can I use std::enable_if in a conversion operator?)を使用して変換がどのように行われたかを制御します。コードはMSVCでコンパイルされますが、GCCとClangでは失敗します。キャスト演算子のためのSFINAE

error: no type named ‘type’ in ‘struct std::enable_if<false, void>’ 

何が問題になる可能性があり、コードをどのように変更する必要がありますか?

コードの下や、ここでの関連部分:http://rextester.com/SYC74124

#include <map> 
#include <string> 
#include <type_traits> 

template < 
    class SubClass, 
    typename EnumType, 
    bool fastStringConvert = true 
> 
class SmartEnum 
{ 
public: 
    template < 
     typename SFINAEPostponer = EnumType, 
     typename = typename std::enable_if<fastStringConvert, void>::type 
    > 
    explicit operator const std::string&() const 
    { 
     auto name = SubClass::names().find((int)value); 
     if (name != SubClass::names().end()) 
     { 
      return name->second; 
     } 
     else 
     { 
      static const std::string na("n.a."); 
      return na; 
     } 
    } 

    template < 
     typename SFINAEPostponer = EnumType, 
     typename = typename std::enable_if<!fastStringConvert, void>::type 
    > 
    explicit operator const std::string() const 
    { 
     auto name = SubClass::names().find((int)value); 
     if (name != SubClass::names().end()) return name->second; 
     else return std::to_string((int)value); 
    } 

protected: 
    typedef const std::map<int, std::string> Names; 
    EnumType value; 
}; 


enum class Foo_type : int { a, b, c }; 

struct Foo : SmartEnum<Foo, Foo_type, true> 
{ 
    typedef SmartEnum<Foo, Foo_type, true> Base; 

    static const Base::Names &names() 
    { 
     static const Base::Names names = { { 0, "a" }, { 1, "b" }, { 2,"c" }}; 
     return names; 
    } 
}; 

答えて

2

あなたは、あなたがハードエラーを持っている他、メソッドからテンプレート引数を使用するようなものがあります:ところで

template < 
    typename SFINAEPostponer = EnumType, 
    bool Cond = !fastStringConvert, 
    typename = typename std::enable_if<Cond, void>::type 
> 
explicit operator const std::string() const 

をデフォルト値の代わりにタイプとしてenable_ifを使用することをお勧めします(無効部分を許可するため)。

template < 
    typename SFINAEPostponer = EnumType, 
    bool Cond = !fastStringConvert, 
    typename std::enable_if<Cond, void>::type* = nullptr 
> 
explicit operator const std::string() const 
+0

Tハンクス、それは助けた。私はこのように最初の議論は必要ない。 – simon

+0

この2つのソリューションの違いは何ですか? – simon

+0

@imimテンプレートパラメータのデフォルト値に基づいて関数をオーバーロードすることはできません。 –

関連する問題