2017-07-18 55 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 

BTW ,最好使用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 hank,它幫助。我甚至不需要這樣的第一個參數。 – simon

+0

你能解釋一下這兩種解決方案有什麼區別嗎? – simon

+0

@simon您不能僅基於模板參數的默認值重載函數,就像您不能基於其參數的默認值重載函數一樣。 –