我有一个模板类,比如说:
template<class T>
class someClient
{
void someCallbackA() {foo_->onA();}
void someCallbackB() {foo_->onB();}
private:
T* foo_;
};
我可以用一堆支持onA
和onB
接口的不同类型T进行实例化。我碰巧有一种情况,我使用的几种不同类型T
中的两种需要一个由someClient
控制的特定行为,因此我需要为这两种类型添加一些函数doBar()
(调用他们Edge1
和Edge2
)。然后,我希望someClient
代码的一部分可以调用foo_->doBar()
但不会在foo_
的类型没有的时候中断。有没有办法使用boost::enable_if
来someClient::doBar()
只为这两种类型调用foo_->doBar()
,但不存在,或者如果类型不是{{1则扩展为空}或Edge1
?
我正在思考:
Edge2
答案 0 :(得分:3)
如果您没有调用成员函数,那么您根本不需要提取任何特殊技巧。模板成员函数仅在需要时才会被专门化(除非您添加显式特化)。所以下面的代码工作正常:
template <typename T> struct Foo
{
void do_foo() { p->foo(); }
void do_bar() { p->bar(); }
T * p;
};
struct A { void foo() {} };
int main()
{
A a;
Foo<A> x = { &a };
x.do_foo();
}
Foo<A>::do_bar
无法编译的事实不是问题,因为成员函数从未实例化。并且p->bar
不是编译器错误,因为p
具有依赖类型,因此仅在第二个查找阶段(从未发生过)中解析该行。
答案 1 :(得分:1)
我认为这可以满足您的需求。我用C ++ 11 <type_traits>
代替了boost:
struct Edge {
void doBar() { std::cout << "did Bar."; }
};
template<typename T>
class someClient
{
public:
template<typename U = T>
typename
std::enable_if<std::is_same<U, Edge>::value, void>::type
doBar() { foo_->doBar(); }
template<typename U = T>
void doBar( typename std::enable_if<!std::is_same<U, Edge>::value, void>::type* = 0 )
{ /* do nothing */ }
private:
T* foo_;
};
int main()
{
someClient<int> i;
someClient<Edge> e;
i.doBar();
e.doBar(); // outputs "did Bar."
}
doBar()
需要成为模板本身才能实现,请在此处解释:std::enable_if to conditionally compile a member function