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

Как позаботиться о повторениях ниже для определений Object::func() без использования макросов?

template <int N> struct Object {};

template <> struct Object<0> {
    // special stuff
    void func();
};

template <> struct Object<1> {
    // special stuff
    void func();
};

template <> struct Object<2> {
    // special stuff
    void func();
};

template <int N> struct Thing {};

void Object<0>::func() {
    Thing<0> a;
    // do stuff with a
}

void Object<1>::func() {
    Thing<1> a;
    // do exact same stuff with a
}

void Object<2>::func() {
    Thing<2> a;
    // do exact same stuff with a
}

Частное наследование с базой, имеющей шаблон int N? Мета-шаблоны? CRTP? Я не могу понять это. Обратите внимание, что

// special stuff

означает, что шаблонные специализации необходимы — я просто не показываю, как они специализируются. Я показываю только одну функцию func(), которая практически идентична всем им.


person prestokeys    schedule 09.07.2014    source источник
comment
Обратите внимание, что вы можете явно специализировать отдельные функции-члены шаблона класса. Так что, может быть, нет необходимости в явной специализации всего шаблона класса?   -  person dyp    schedule 09.07.2014


Ответы (2)


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

Ниже приведен код, который я только что написал и протестировал в Visual Studio 2013:

#include <iostream>

template <int N> struct Thing { int x; Thing() : x(N) {}; };

template <int N, template<int N> class T> struct Object { void func(); };

template <int N, template<int N> class T> void Object<N, T>::func()
{
    T<N> a;
    std::cout << a.x << std::endl;
};

int main()
{
    Object<0, Thing> obj0;
    Object<11, Thing> obj11;
    Object<22, Thing> obj22;
    obj0.func();
    obj11.func();
    obj22.func();
    return 0;
}

Этот код напечатает:

0 11 22

person dguan    schedule 09.07.2014

Используя наследование, вы можете избежать специализации общего кода. Как насчет:

template <int N> struct ObjectBase {
  void func();
};

template <int N> struct Thing {};

template <int N>
void ObjectBase<N>::func() {
    Thing<N> a;
    // do stuff with a
}

template <> struct Object<0>: private ObjectBase<0> {
    // special stuff
};

template <> struct Object<1>: private ObjectBase<1> {
    // special stuff
};

template <> struct Object<2>: private ObjectBase<2> {
    // special stuff
};
person Suma    schedule 09.07.2014
comment
Возможно, плюс объявление использования, чтобы снова сделать func общедоступным. Или публичное наследование. - person dyp; 09.07.2014
comment
@Suma для предотвращения/уменьшения раздувания кода — базовый класс не должен быть шаблоном - person spin_eight; 09.07.2014
comment
@spin_eight Это должен быть шаблон из-за реализации func. - person Suma; 09.07.2014