请考虑以下代码段:
#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;
}
是否可以只编译一个handleEvent
方法,具体取决于提供的模板类类型?
通过上面的示例,编译器提供:
prog.cpp:18:3: error: 'typename std::enable_if<std::is_same<MapType, UseMap>::value, bool>::type MyClass<MapType>::handleEvent(int)' cannot be overloaded
答案 0 :(得分:3)
我认为你必须制作重载的功能模板。
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();
}
这通过编译。 (clang-600.0.54 with -std=c++11
)
答案 1 :(得分:1)
找到答案的补充:你也可以从一个易于专门化的基类继承。
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();
}
};
}
我觉得我过于复杂了声明顺序,请仔细检查:)