SFINAE 用于铸造操作员

sim*_*mon 1 c++ gcc sfinae enable-if typecast-operator

我有一个类,它包装一个枚举并为其提供字符串转换。现在我引入了模板参数 \'fastStringConvert\',它控制如何使用 SFINAE 进行转换(可在此处找到:how can I use std::enable_if in a conversion operator?)。代码在 MSVC 下编译,但在 GCC 和 Clang 下失败。

\n\n
error: no type named \xe2\x80\x98type\xe2\x80\x99 in \xe2\x80\x98struct std::enable_if<false, void>\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n\n

可能是什么问题以及我应该如何更改代码?

\n\n

下面或此处代码的相关部分:http://rextester.com/SYC74124

\n\n
#include <map>\n#include <string>\n#include <type_traits>\n\ntemplate <\n    class SubClass, \n    typename EnumType, \n    bool fastStringConvert = true\n>\nclass SmartEnum\n{\npublic:\n    template <\n        typename SFINAEPostponer = EnumType,\n        typename = typename std::enable_if<fastStringConvert, void>::type\n    >\n    explicit operator const std::string&() const \n    {\n        auto name = SubClass::names().find((int)value);\n        if (name != SubClass::names().end())\n        {\n            return name->second;\n        }\n        else\n        {\n            static const std::string na("n.a.");\n            return na;\n        }\n    }\n\n    template <\n        typename SFINAEPostponer = EnumType,\n        typename = typename std::enable_if<!fastStringConvert, void>::type\n    >\n    explicit operator const std::string() const\n    {\n        auto name = SubClass::names().find((int)value);\n        if (name != SubClass::names().end()) return name->second;\n        else return std::to_string((int)value);\n    }\n\nprotected:\n    typedef const std::map<int, std::string> Names;\n    EnumType value;\n};\n\n\nenum class Foo_type : int { a, b, c }; \n\nstruct Foo : SmartEnum<Foo, Foo_type, true>\n{ \n    typedef SmartEnum<Foo, Foo_type, true> Base; \n\n    static const Base::Names &names() \n    { \n        static const Base::Names names = { { 0, "a" }, { 1, "b" }, { 2,"c" }}; \n        return names; \n    } \n};\n
Run Code Online (Sandbox Code Playgroud)\n

Jar*_*d42 5

您必须使用方法中的模板参数,否则会出现硬错误,例如:

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

顺便说一句,最好用作enable_if类型而不是默认值(以允许禁用部分):

template <
    typename SFINAEPostponer = EnumType,
    bool Cond = !fastStringConvert,
    typename std::enable_if<Cond, void>::type* = nullptr
>
explicit operator const std::string() const
Run Code Online (Sandbox Code Playgroud)