шаблонная специализация шаблонного класса - PullRequest
7 голосов
/ 23 августа 2009

Я хочу специализировать следующую функцию-член:

class foo {
    template<typename T>
    T get() const;
};

К другому классу bar, что также зависит от шаблонов.

Например, я бы хотел, чтобы bar было std::pair с некоторыми параметрами шаблона, что-то вроде этого:

template<>
std::pair<T1,T2> foo::get() const
{
    T1 x=...;
    T2 y=...;
    return std::pair<T1,T2>(x,y);
}

Где T1 и T2 также являются шаблонами. Как это может быть сделано? Насколько я знаю, это должно быть возможно.

Так что теперь я могу позвонить:

some_foo.get<std::pair<int,double> >();

Полный / окончательный ответ:

template<typename T> struct traits;
class foo {
    template<typename T>
    T get() const
    {
       return traits<T>::get(*this); 
    }
};

template<typename T>
struct traits {
    static T get(foo &f)
    {
        return f.get<T>();
    }
};

template<typename T1,typename T2>
struct traits<std::pair<T1,T2> > {
        static std::pair<T1,T2> get(foo &f)
        {
                T1 x=...;
                T2 y=...;
                return std::make_pair(x,y);
        }
};

Ответы [ 2 ]

8 голосов
/ 23 августа 2009

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

class foo {
   ...
};


template<typename T>
struct getter {
  static T get(const foo& some_foo);
};

template<typename T1, typename T2>
struct getter< std::pair<T1, T2> > {
static std::pair<T1, T2> get(const foo& some_foo) {
    T1 t1 = ...;
    T2 t2 = ...;
    return std::make_pair(t1, t2);
};

и затем назовите это как

getter<std::pair<int, double> >::get(some_foo);

хотя. Возможно, вам придется немного поэкспериментировать с friend кораблем или видимостью, если get действительно требуется для функции-члена.

Чтобы уточнить предложение sbi:

class foo {
   ...
   template<typename T>
   T get() const;
};

template<typename T>
T foo::get() const
{
  return getter<T>::get(*this);
  /*            ^-- specialization happens here */
}

И теперь вы вернулись к возможности сказать

std::pair<int,double> p = some_foo.get<std::pair<int, double> >();
1 голос
/ 23 августа 2009

Вам нужно перегрузить функцию-член для пары, как в

template <T, V> std::pair<T, V> foo::get()

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

Если вместо этого вам нужна специализация, например, для std :: vector, то есть для контейнера с шаблоном с одним параметром, вы должны быть осторожны, поскольку компилятор может сбить с толку, если вы захотите создать экземпляр специализация шаблона, где шаблоном T является std :: vector или специализация для перегрузки,

template <T> std::<vector <T> foo::get() const 

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

template <>,

но вы опускаете два неопределенных типа, T1 и T2.

...