C++ 类成员重载方法的SFINAE

C++ 类成员重载方法的SFINAE,c++,templates,member,sfinae,enable-if,C++,Templates,Member,Sfinae,Enable If,考虑一下这个片段: #include <type_traits> struct UseMap; struct NoMap; template<typename MapType = NoMap> class MyClass { public: typename std::enable_if<std::is_same<MapType, NoMap>::value, bool>::type handleEvent(int someVal)

考虑一下这个片段:

#include <type_traits>

struct UseMap;
struct NoMap;

template<typename MapType = NoMap>
class MyClass
{
public:

  typename std::enable_if<std::is_same<MapType, NoMap>::value, bool>::type
  handleEvent(int someVal)
  {
    return doSomething();
  }

  typename std::enable_if<std::is_same<MapType, UseMap>::value, bool>::type
  handleEvent(int someVal)
  {
    return doSomethingDifferent();
  }

  bool doSomething() {};
  bool doSomethingDifferent() {};
};

int main() {
  MyClass obj1();
  MyClass<UseMap> obj2();
  return 0;
}

我认为您必须创建重载函数模板

template<typename T = MapType,
  typename std::enable_if<
    std::is_same<T, NoMap>::value>::type *& = nullptr>
bool
handleEvent(int someVal)
{
  return doSomething();
}

template<typename T = MapType,
  typename std::enable_if<
    std::is_same<T, UseMap>::value>::type *& = nullptr>
bool
handleEvent(int someVal)
{
  return doSomethingDifferent();
}
template::type*&=nullptr>
布尔
handleEvent(int-someVal)
{
返回doSomething();
}
模板::类型*&=nullptr>
布尔
handleEvent(int-someVal)
{
返回doSomethingDifferent();
}

这将通过编译。(带有
-std=c++11
)的clang-600.0.54

我认为您必须创建重载函数模板

template<typename T = MapType,
  typename std::enable_if<
    std::is_same<T, NoMap>::value>::type *& = nullptr>
bool
handleEvent(int someVal)
{
  return doSomething();
}

template<typename T = MapType,
  typename std::enable_if<
    std::is_same<T, UseMap>::value>::type *& = nullptr>
bool
handleEvent(int someVal)
{
  return doSomethingDifferent();
}
template::type*&=nullptr>
布尔
handleEvent(int-someVal)
{
返回doSomething();
}
模板::类型*&=nullptr>
布尔
handleEvent(int-someVal)
{
返回doSomethingDifferent();
}

这将通过编译。(带有
-std=c++11
)的clang-600.0.54

补充了findall的答案:您还可以从易于专门化的基类继承

struct UseMap;
struct NoMap;

template<typename>
class MyClass;

namespace detail {
  // Container for the handleEvent() function
  template<typename>
  struct MyClassHandler;
}

// Enter CRTP !
template<typename MapType = NoMap>
class MyClass : detail::MyClassHandler<MyClass<MapType>>
{
    friend class detail::MyClassHandler<MyClass<MapType>>;
public:
  using detail::MyClassHandler<MyClass<MapType>>::handleEvent;

  bool doSomething() {};
  bool doSomethingDifferent() {};
};

// Actual specializations now that the full definition of MyClass is in scope
namespace detail {
  template<>
  struct MyClassHandler<MyClass<NoMap>> {
    bool handleEvent(int someVal)
    {
      return static_cast<MyClass<NoMap>*>(this)->doSomething();
    }
  };

  template<>
  struct MyClassHandler<MyClass<UseMap>> {
    bool handleEvent(int someVal)
    {
      return static_cast<MyClass<UseMap>*>(this)->doSomethingDifferent();
    }
  };
}
struct-UseMap;
结构NoMap;
模板
类MyClass;
名称空间详细信息{
//handleEvent()函数的容器
模板
结构MyClassHandler;
}
//进入CRTP!
模板
类MyClass:detail::MyClassHandler
{
好友类详细信息::MyClassHandler;
公众:
使用detail::MyClassHandler::handleEvent;
bool doSomething(){};
bool doSomethingDifferent(){};
};
//现在MyClass的完整定义在范围内,实际的专门化
名称空间详细信息{
模板
结构MyClassHandler{
bool handleEvent(int-someVal)
{
返回static_cast(this)->doSomething();
}
};
模板
结构MyClassHandler{
bool handleEvent(int-someVal)
{
返回static_cast(this)->doSomethingDifferent();
}
};
}

我觉得我把声明顺序复杂化了一点,再次检查welcome:)

补充了findall的答案:您还可以从一个易于专门化的基类继承

struct UseMap;
struct NoMap;

template<typename>
class MyClass;

namespace detail {
  // Container for the handleEvent() function
  template<typename>
  struct MyClassHandler;
}

// Enter CRTP !
template<typename MapType = NoMap>
class MyClass : detail::MyClassHandler<MyClass<MapType>>
{
    friend class detail::MyClassHandler<MyClass<MapType>>;
public:
  using detail::MyClassHandler<MyClass<MapType>>::handleEvent;

  bool doSomething() {};
  bool doSomethingDifferent() {};
};

// Actual specializations now that the full definition of MyClass is in scope
namespace detail {
  template<>
  struct MyClassHandler<MyClass<NoMap>> {
    bool handleEvent(int someVal)
    {
      return static_cast<MyClass<NoMap>*>(this)->doSomething();
    }
  };

  template<>
  struct MyClassHandler<MyClass<UseMap>> {
    bool handleEvent(int someVal)
    {
      return static_cast<MyClass<UseMap>*>(this)->doSomethingDifferent();
    }
  };
}
struct-UseMap;
结构NoMap;
模板
类MyClass;
名称空间详细信息{
//handleEvent()函数的容器
模板
结构MyClassHandler;
}
//进入CRTP!
模板
类MyClass:detail::MyClassHandler
{
好友类详细信息::MyClassHandler;
公众:
使用detail::MyClassHandler::handleEvent;
bool doSomething(){};
bool doSomethingDifferent(){};
};
//现在MyClass的完整定义在范围内,实际的专门化
名称空间详细信息{
模板
结构MyClassHandler{
bool handleEvent(int-someVal)
{
返回static_cast(this)->doSomething();
}
};
模板
结构MyClassHandler{
bool handleEvent(int-someVal)
{
返回static_cast(this)->doSomethingDifferent();
}
};
}
我觉得我把申报单复杂化了一点,再次检查欢迎:)