Как вызвать функцию шаблона класса с параметром

0

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

Моя ошибка выглядит так:

In PtrAllocator<T, Pool>::allocate(PtrAllocator<T, Pool>::size_type, const void*)': expected primary-expression before '>' token

In PtrAllocator<T, Pool>::max_size() const': expected primary-expression before '>' token

Мой код выглядит так:

template<typename T, typename Pool>
class PtrAllocator : public BasicAllocator<T>
{
    private:
        Pool pool;

    public:
        typedef typename BasicAllocator<T>::pointer pointer;
        typedef typename BasicAllocator<T>::size_type size_type;
        typedef typename BasicAllocator<T>::value_type value_type;

        template<typename U>
        struct rebind {typedef PtrAllocator<U, Pool> other;};

        PtrAllocator(Pool&& pool) : pool(pool) {}

        pointer allocate(size_type n, const void* hint = 0) {return static_cast<pointer>(pool.allocate<T>(n, hint));}
        void deallocate(void* ptr, size_type n) {pool.deallocate(static_cast<pointer>(ptr), n);}
        size_type max_size() const {return pool.max_size<T>();}
};

class Pool
{
    public:
        template<typename T>
        void* allocate(std::size_t n, const void* hint = 0) {return ::operator new(n * sizeof(T));}

        template<typename T>
        void deallocate(T* ptr, std::size_t n) {::operator delete(ptr);}

        template<typename T>
        std::size_t max_size() const {return std::numeric_limits<std::size_t>::max() / sizeof(T);}
};

int main()
{
    PtrAllocator<int, Pool> alloc = PtrAllocator<int, Pool>(Pool());
    std::vector<int, PtrAllocator<int, Pool>> v(alloc);
    v.resize(1000); //this line is causing the error.
}

Ошибки происходят, когда PtrAllocator::allocate вызовы Pool::allocate PtrAllocator::allocate. То же самое происходит с max_size но не происходит deallocate. Любые идеи, почему это не позволит мне указать параметр шаблона?

Теги:

1 ответ

4
Лучший ответ

Вам нужно сообщить компилятору, что allocate является шаблоном, иначе выражение будет неоднозначным:

pool.template allocate<T>(n, hint)

Объяснение см. В разделе Где и почему я должен поставить ключевые слова "шаблон" и "имя-тип"? ,

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

struct my_pool {
    int allocate = 0; // allocate is a data member, not a template!
};

template <typename Pool>
void foo() {
    Pool pool;
    int T = 0, n = 0, hint = 0;
    pool.allocate<T>(n, hint); // *
}

int main() {
    foo<my_pool>();
}

Строка, отмеченная звездочкой, имеет то же выражение, что и у вас, но это означает нечто совершенно другое. Это фактически эквивалентно (pool.allocate < T) > (n, hint). То есть, < и > больше не являются параметрами шаблонов аргументов - они являются реляционными операторами! Я сравниваю pool.allocate данных pool.allocate с T

  • 0
    Я никогда не видел этот синтаксис в своей жизни. шаблон, следующий за оператором точки ..: o. Спасибо. Это решило мою проблему. Я приму этот ответ, как только он позволит мне. Я также добавил ссылку, которую вы мне дали.
  • 0
    @CantChooseUsernames Я добавил пример, чтобы продемонстрировать, почему это выражение неоднозначно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню