让我们考虑下面的类,它检查提供的类型是否为字符串,并使用类型特征根据结果调用不同的函数。原始源具有对Obj的类型依赖性,这是一个简化的示例:
template <typename Obj>
class example {
public:
template <bool IdIsString = std::is_same<std::string, Obj>::value>
typename std::enable_if<IdIsString, void>::type
doStuff() {
this->object->doSomething();
}
template <bool IdIsString = std::is_same<std::string, Obj>::value>
typename std::enable_if<!IdIsString, void>::type
doStuff() {
this->object->doSomethingElse();
}
private:
AnyObject object;
};
如何在不提供定义中的每个类型特征的情况下,将定义(例如将其存储在example_inline.hpp中)与类解耦?
理想的解决方案如下:
// header.hpp
template <typename Obj>
class example {
public:
void doStuff();
}
// header_inline.hpp
template <typename Obj>
template <bool IdIsString = std::is_same<std::string, Obj>::value>
typename std::enable_if<IdIsString, void>::type
example::doStuff() {
// ...
}
// ...
以上显然是不可能的。一种解决方案是将type_trait函数与类分离并将其放入详细命名空间,但这意味着我必须始终将AnyObject(在这种意义上,由函数修改的所有对象)传递给它不是很优雅。
这个问题有一个很好的解决方案吗?我非常希望有问题的标题可以轻松阅读,而不会因为大量的enable_if而混乱。
感谢您对此事的任何意见。
答案 0 :(得分:3)
您可以根据std::is_same
:
template<typename T>
class example
{
private:
void doStuff(std::true_type)
{
obj->doSomething();
}
void doStuff(std::false_type)
{
obj->doSomethingElse();
}
public:
void doStuff()
{
doStuff(std::is_same<T, std::string>{});
}
};
答案 1 :(得分:2)
在这个简单的例子中,您还可以在类模板的模板参数上专门化doStuff
:
#include <iostream>
#include <string>
template<class T>
struct example
{ void doStuff(); };
template<class T>
void example<T>::doStuff()
{ std::cout<<"default\n"; }
template<>
void example<std::string>::doStuff()
{ std::cout<<"string\n"; }
int main()
{
example<int>{}.doStuff();
example<std::string>{}.doStuff();
}