Как выбрать альтернативную реализацию функции-члена в зависимости от аргумента шаблона? - PullRequest
1 голос
/ 29 февраля 2012

Предположим, у меня есть этот класс:

template</*some other parameters here */class toggle>
class Foo
{
   void function();
   //Lots of other non-parametrized member functions
}

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

Подвох: Простая специализация всего класса нереалистична, поскольку у Foo будет много других методов, не зависящих от этого переключателя, которые также должны будут быть реализованы снова, что делает все огромной тратойпространства.

Ответы [ 4 ]

6 голосов
/ 29 февраля 2012

Я думаю, это то, что вы просите:

#include <iostream>
#include <string>

template <class toggle>
class Foo
{
public:
    void function() { std::cout << "Default\n"; }
};

template <>
void Foo<int>::function() { std::cout << "int\n"; }

int main ()
{
    Foo<std::string>().function();
    Foo<int>().function();

    return 0;
}

Вывод:

Default
int
3 голосов
/ 29 февраля 2012

Вместо этого вам может потребоваться специализировать базовый класс:

template<class toggle>
class FooFunction {
public:
    void function();
};

template<>
class FooFunction<blah> {
public:
    void function();
};

template<class toggle>
class Foo : public FooFunction<toggle> {
    //Lots of other non-parametrized member functions
};
1 голос
/ 29 февраля 2012

Специализация шаблона, попробуйте отладить это и обратите внимание, что не все функции нуждаются в специализации:

template <class T> class Spec
{
public:
    void Func()
    {
    }

    void Func2()
    {
    }

};


void Spec<double>::Func()
{

}

int main( int argc, char *argv )
{

    Spec<int> spec1;
    spec1.Func();
    spec1.Func2();

    Spec<double> spec2;
    spec2.Func();
    spec2.Func2();


    return 0;
}
1 голос
/ 29 февраля 2012

Если создание function приемлемого для вас перегруженного набора шаблонов функций, то:

// toggle is not a dependent type so we solve that
template<
    typename T = toggle
    , typename = typename std::enable_if<
        std::is_same<T, int>::value
    >::type
>
void function()
{ /* implementation for int */ }

template<
    typename T = toggle
    , typename = typename std::enable_if<
        !std::is_same<T, int>::value
    >::type
    // dummy parameter to make this declaration distinct from the previous one
    typename = void
>
void function()
{ /* implementation for others */ }

Это написано в стиле C ++ 11, но может быть настроено для работы с C ++03.(Это может зависеть от того, что SFINAE в некоторых случаях является серой областью для C ++ 03, но я недостаточно знаю о правилах.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...