静态嵌套bool是否会帮助我禁用某些类型的调用,还是有更简洁的方式?

时间:2012-09-04 22:23:40

标签: c++ templates boost

我有一个模板类,比如说:

template<class T>
class someClient
{
void someCallbackA() {foo_->onA();}
void someCallbackB() {foo_->onB();}

private:
T* foo_;
};

我可以用一堆支持onAonB接口的不同类型T进行实例化。我碰巧有一种情况,我使用的几种不同类型T中的两种需要一个由someClient控制的特定行为,因此我需要为这两种类型添加一些函数doBar()(调用他们Edge1Edge2)。然后,我希望someClient代码的一部分可以调用foo_->doBar()但不会在foo_的类型没有的时候中断。有没有办法使用boost::enable_ifsomeClient::doBar()只为这两种类型调用foo_->doBar(),但不存在,或者如果类型不是{{1则扩展为空}或Edge1

我正在思考:

Edge2

2 个答案:

答案 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