Частичная специализация функции класса с шаблонным аргументом

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

template<class I, class C = std::queue<I>>
class Queue
{
    C items;
public:
    I* Top()
    {
        std::cout << "this is a queue" << std::endl;
        return &items.front();
    }
};

template<class I>
void I* Queue<I, std::priority_queue<I>>::Top()
{
    std::cout << "this is a priority_queue" << std::endl;
    return &items.top();
}

Однако этот фрагмент кода вызывает много ошибок компиляции. Кто-нибудь может подсказать мне, что я иду в неправильном направлении разработки класса шаблона? Спасибо.


person Elliott    schedule 24.10.2013    source источник
comment
Что такое void I* в любом случае? И независимо от того, items имеет тип C, и никакая магия в одной функции-члене не изменит этого.   -  person WhozCraig    schedule 24.10.2013
comment
Ой... извините... это опечатка. Тип возвращаемого значения функции Top() должен быть I* вместо void I*.   -  person Elliott    schedule 25.10.2013


Ответы (1)


Вы пытаетесь частично специализировать шаблон функции (члена). Шаблоны функций не могут быть частично специализированы в C++. Вам придется частично специализировать весь класс или найти другие способы делать то, что вы хотите. Например, вы можете использовать трейт в Top():

I* Top()
{
    return MyQueueTraits<I, C>::GetTop(items);
}

template <class I, class C>
struct MyQueueTraits
{
  static I* GetTop(C &c) { return &c.front(); }
};

template <class I>
struct MyQueueTraits<I, std::priority_queue<I>>
{
  static I* GetTop(std::pirority_queue<I> &c) { return &c.top(); }
};
person Angew is no longer proud of SO    schedule 24.10.2013
comment
Да! Это работает для моей реализации. Большое спасибо! :) - person Elliott; 24.10.2013