C ++ одна специализация шаблона с несколькими параметрами шаблона - PullRequest
9 голосов
/ 22 сентября 2010

Hallo!

Я бы хотел специализировать только один из двух типов шаблонов. Например. template <typename A, typename B> class X должна иметь специальную реализацию для отдельной функции X<float, sometype>::someFunc().

Пример кода:

main.h:

#include <iostream>

template <typename F, typename I>
class B
{
public:
    void someFunc()
    {
        std::cout << "normal" << std::endl;
    };

    void someFuncNotSpecial()
    {
        std::cout << "normal" << std::endl;
    };
};

template <typename I>
void B<float, I>::someFunc();

main.cpp:

#include <iostream>
#include "main.h"

using namespace std;

template <typename I>
void B<float, I>::someFunc()
{
    cout << "special" << endl;
}

int main(int argc, char *argv[])
{
    B<int, int> b1;
    b1.someFunc();
    b1.someFuncNotSpecial();

    B<float, int> b2;
    b2.someFunc();
    b2.someFuncNotSpecial();
}

Компиляция не удалась для class B. Правда ли, что в С ++ это невозможно? Какой будет лучший обходной путь?

[править]

template <float, typename I> void B<float, I>::someFunc(); приводит к main.h: 26: ошибка: «float» не является допустимым типом для параметра константы шаблона

template <typename I> void B<float, I>::someFunc(); приводит к main.h: 27: ошибка: недопустимое использование неполного типа "класс B"

И я использую gcc.

[править]

Я не хочу специализировать весь класс, поскольку есть другие функции, которые не имеют специализации.

Ответы [ 3 ]

18 голосов
/ 22 сентября 2010

Вы должны предоставить частичную специализацию шаблона класса B:

template <typename I>
class B<float, I>
{
public:
    void someFunc();
};

template <typename I>
void B<float, I>::someFunc()
{
    ...
}

Вы также можете просто определить someFunc внутри специализации.

Однако, , если вы хотите специализировать только функцию, а не класс, делайте e. г.

template <typename F, typename I>
void someFunc(F f, I i) { someFuncImpl::act(f, i); }

template <typename F, typename I>
struct someFuncImpl { static void act(F f, I i) { ... } };

// Partial specialization
template <typename I>
struct someFuncImpl<float, I> { static void act(float f, I i) { ... } };

Но вы не можете специализировать шаблон функции без этого трюка.

5 голосов
/ 22 сентября 2010

Хотя вы можете полностью специализировать функции-члены шаблона класса, вы не можете _спарциально специализировать функции-члены.- Андрей Александреску

Частичная Класс Специализация объясняется другими авторами.

Вы можете, однако, использовать перегрузку:

template <class T, class U> T fun(U obj); // primary template
template <class U> void Fun<void, U>(U obj); // illegal pertial
// specialization
template <class T> T fun (Window obj); // legal (overloading)

Если вы хотите углубиться в это, вы можете прочитать об этой проблеме подробно в "Modern C ++ Design" А. Александреску.

0 голосов
/ 21 октября 2015

Решение 1. переместить всю реализацию в базовый класс, такой как B_Base. затем специализируемся на float, чтобы переопределить someFunc. как показано ниже

    template <typename F, typename I>
    class B : B_Base<F, I>
    {
    }

    template <typename I>
    class B<float, I> : B_Base<flat, I>
    {
    public:
        void someFunc() {....}
    };

Решение 2. используйте перегрузку функции, поместите float как input или boost :: is_same для отправки. к сожалению, у вас функция someFunc не имеет параметров. так что нужно сменить интерфейс.

...