“X”的 template-id 'empty<>' 与任何模板声明都不匹配,候选者为:“X”

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

提问人:Tini4 提问时间:7/3/2023 更新时间:7/3/2023 访问量:31

问:

我正在尝试为我的班级进行模板专业化。我有一个头文件和一个 sorce 文件:

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();
}

在模板专用化的所有定义中,我收到以下错误:

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);
      |          ^~~~

候选人和我写的一样。 同样的错误也适用于 和 。std::string Stack<std::string>::pop()std::string Stack<std::string>::top() constbool Stack<std::string>::empty() const

我还尝试将所有代码放在同一个文件中,但遇到了相同的错误。

C++ OOP 模板 template-specialization

评论


答:

2赞 user17732522 7/3/2023 #1

语法错误。 始终引入显式专用化,但您不会尝试显式专用化模板的成员函数。您正在尝试定义模板的显式专用化的成员函数,该模板本身不是模板。template<>

因此,只需删除显式专用类的类外成员定义即可。template<>

此外,由于类及其成员函数的显式专用化本身不是模板化实体,因此您需要在单个转换单元 () 文件中定义成员函数或标记它们。one-definition-rule 适用于它们的方式与适用于普通函数(而不是模板化函数)的方式相同。.cppinline

评论

0赞 Tini4 7/3/2023
谢谢,删除 s 工作。我不明白最后一段,但代码编译了。template<>
0赞 user17732522 7/3/2023
@Tini4 如果将标头包含在多个 .你不能在标头中定义显式专用类的成员函数,就像你不能对普通(非模板)函数这样做一样。这仅适用于模板化的实体或函数(在后一种情况下,必须在使用函数 (odr-) 的每个转换单元中定义函数。如果您要写入文件或文件,则会遇到完全相同的问题。.cppinlineinlinevoid f() { }.h.tpp