看一个像这样的简单模板场景:
class A {
public:
int work();
};
class B {
public:
int work();
};
class ObjectManager {
public:
static void manage( A& obj );
// manage not defined for class B
};
template<class T>
doStuff( T t ) {
t.work();
....
ObjectManager::manage(t);
};
A a;
B b;
doStuf(a);
doStuff(b);
Run Code Online (Sandbox Code Playgroud)
我想知道,实现条件调用的最简洁方法是什么ObjectManager::manage?模板函数应该在编译时确定ObjectManager::manage(T t)是否为给定定义,T并且只在它被激活时激活某些代码行.我想有一些更多嵌套模板调用的解决方案,但对我来说最好只保留一个功能.
请注意,目前您的班级成员都是私人的.它们应该公之于众.
template<class T>
auto call_manage(T* t) -> decltype(ObjectManager::manage(*t)){
return ObjectManager::manage(*t);
}
void call_manage(...) {}
template<class T>
void doStuff( T t ) {
t.work();
//....
call_manage(std::addressof(t)); // smack whoever overloaded unary
// operator & in the head first
}
Run Code Online (Sandbox Code Playgroud)
如果表达式ObjectManager::manage(*t)格式正确,则函数模板的替换成功,这总是比匹配更好...,因此调用它.否则,do-nothing过载是唯一可行的功能.
演示.
对于那些喜欢参考的人:
template<class T>
auto call_manage(T& t) -> decltype(ObjectManager::manage(t)){
return ObjectManager::manage(t);
}
template<class... T>
void call_manage(T&&...) {}
template<class T>
void doStuff( T t ) {
t.work();
//....
call_manage(t);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,单参数重载比函数模板的部分排序规则更可靠于可变参数版本,并且如果两者同样可行,则通过重载决策选择.您也可以接听T&& t和拨打电话manage(std::forward<T>(t)),以便完美转发.
演示.