Search code examples
c++classooptemplatestemplate-specialization

template-id 'empty<>' for 'X' does not match any template declaration, candidate is: 'X'


I am trying to do template specialization for my class. I have a header file and a sorce file:

stack.h

#ifndef EX9_STACK_H
#define EX9_STACK_H

#include <deque>
#include <string>
#include <vector>

template <typename T>
class Stack
{
public:
    void push(T const& x);
    T pop();
    T top() const;
    bool empty() const;

private:
    std::vector<T> m_elems;
};

template <>
class Stack<std::string>
{
public:
    void push(std::string const& x);
    std::string pop();
    std::string top() const;
    bool empty() const;

private:
    std::deque<std::string> m_elems;
};

#include "stack.tpp"

#endif // EX9_STACK_H

stack.tpp

#include "stack.h"

template <typename T>
void Stack<T>::push(T const& x)
{
    m_elems.push_back(x);
}

template <typename T>
T Stack<T>::pop()
{
    T x;
    x = top();
    m_elems.pop_back();
    return x;
}

template <typename T>
T Stack<T>::top() const
{
    return m_elems.back();
}

template <typename T>
bool Stack<T>::empty() const
{
    return m_elems.empty();
}

template <>
void Stack<std::string>::push(std::string const& x)
{
    m_elems.push_back(x);
}

template <>
std::string Stack<std::string>::pop()
{
    std::string x;
    x = top();
    m_elems.pop_back();
    return x;
}

template <>
std::string Stack<std::string>::top() const
{
    return m_elems.back();
}

template <>
bool Stack<std::string>::empty() const
{
    return m_elems.empty();
}

On all the definitions of template specialization I get the following error:

stack.tpp:31:6: error: template-id 'push<>' for 'void Stack<std::__cxx11::basic_string<char> >::push(const string&)' does not match any template declaration
   31 | void Stack<std::string>::push(std::string const& x)
      |      ^~~~~~~~~~~~~~~~~~
stack.h:25:10: note: candidate is: 'void Stack<std::__cxx11::basic_string<char> >::push(const string&)'
   25 |     void push(std::string const& x);
      |          ^~~~

The candidate is the same as what I wrote. The same error is also for std::string Stack<std::string>::pop(), std::string Stack<std::string>::top() const and bool Stack<std::string>::empty() const.

I have also tryed to put all the code in the same file, but I get the same errors.


Solution

  • The syntax is wrong. template<> always introduces an explicit specialization, but you are not trying to explicitly specialize the member function of a template. You are trying to define a member function of an explicit specialization of a template, which itself is not a template.

    So just remove the template<> on the out-of-class member definitions for the explicitly specialized class.

    Also, because the explicit specialization of the class and its member functions are not themselves templated entities, you need to either define the member functions in a single translation unit (.cpp) file or mark them inline. The one-definition-rule applies to them in the same way it applies to normal functions, not templated ones.