Поможет ли статический вложенный bool отключить вызов для определенных типов или есть более чистый способ?

У меня есть шаблон класса, скажем:

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

private:
T* foo_;
};

который я могу создать с кучей разных типов T, которые поддерживают onA а также onB интерфейс. У меня случается случай, когда два из нескольких разных типов T Я использую нуждается в особом поведении, контролируемом someClient поэтому мне нужно добавить некоторую функцию doBar() к этим двум типам (назовите их Edge1 а также Edge2). Тогда я хочу часть someClient код для вызова foo_->doBar() но без разрыва, когда тип foo_ не имеет этого Есть ли способ использовать boost::enable_if иметь someClient::doBar() который позвонит foo_->doBar() только для этих двух типов, но не быть там или расширяться до нуля, если типы не Edge1 или же Edge2?

Я думал так:

template <class T, enable_if<mpl_or<is_same<T,Edge1>, is_same<T,Edge2> > >
someClient<T>::doBar() {foo_->doBar();}

1

Решение

Я думаю, что это делает то, что вы хотите. Я использовал C ++ 11 <type_traits> вместо буста:

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 для условной компиляции функции-члена

1

Другие решения

Вам не нужно тянуть какие-либо специальные трюки на всех, если вы просто не делаете вызов функции-члены, которые не имеют смысла. Функции-члены шаблона специализируются только при необходимости (если вы не добавите явную специализацию). Так что следующий код работает нормально:

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 имеет зависимый тип, и строка, таким образом, анализируется только во второй фазе поиска (что никогда не происходит).

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector