在 C++ 的模板中使用运算符

Posted

技术标签:

【中文标题】在 C++ 的模板中使用运算符【英文标题】:use operators in templates in c++ 【发布时间】:2009-07-17 05:23:16 【问题描述】:

我正在尝试使用指针实现一个 List 类,并尝试实现一个函数 LOCATE(T x),其中 T 用于模板,如果找到则返回元素 x 的第一个位置,否则返回最后一个位置 + 1。

我的功能代码是

template<class T>
    int List<T>::locate(T n) const
    
        int size = end();
        Node<T> * p = head_;

        for (int i = 0; i < size; i++)
        
            if (p->data() == n) // fails on this line
                return i;
            p = p->link();
        
        return size; // if no match found
     

我用 T 作为字符串初始化我的列表作为

List<string> myList;

但我收到一条错误消息

'bool std::operator ==(const std::istreambuf_iterator<_elem> &,const std::istreambuf_iterator<_elem> &)' : 无法推导出 'const std::istreambuf_iterator 的模板参数<_elem> &' 来自 'std::string

为什么即使为字符串类定义了“==”运算符,也会出现错误? '

Node的代码是

template<typename T>
class Node

  public:

    // Constructors
    Node();
    Node(T d, Node<T> * l = NULL);

    //Inspectors 
    T data() const;
    Node<T> * link() const;

    // Mutators 
    void data(T d); // assigns new value to Node
    void link(Node<T> * l); // points this Node to a different one

    // Destructor
    ~Node();

    private:
  Node<T> * link_;
  T data_;
;

template<typename T>
    T Node<T>::data() const
    
        return data_;
    
template<typename T>
    Node<T>* Node<T>::link() const
    
        return link_;
    

调用代码是

List<string> test;
test.add("abc");
cout << test.locate("abc") << endl;

【问题讨论】:

能贴出Node的代码吗? 你对 Node 的定义是什么样的?完整的调用代码,以“List myList;”开头的代码,如上所示?谢谢。 刚刚发布了Node的定义和调用代码 您应该发布所有内容。这段代码看起来不错。 如果我删除了包含 '==' 运算符的行,其余代码将完美运行。 【参考方案1】:

在没有深入了解您的代码的情况下,我注意到了几个问题。

首先,

locate(T n) 

应该是

locate(const T& n)

这保存了一个可能的 n 副本

问一个愚蠢的问题,你确定你已经完成了吗:

 #include <string>

【讨论】:

很好地询问包含问题 干得好..根据 OP 的最新评论,包含文件原来是问题所在。 “我注意到几个问题。”你只发现了一个问题。 我指出了两个。 “定位”方法,以及丢失包含文件的可能性。【参考方案2】:

试试:

if( n.compare(p->data()) == 0 )

string::compare documentation

正如下面的 cmets 所指出的, operator== 应该可以工作。请仔细检查您是否有

#include <string>
using std::string;

【讨论】:

这一切都很好......但你真的没有解决问题。 operator== 应该可以工作。 @rlbond 绝对是。我知道一些字符串文档 (cplusplus.com/reference/string/string) 不包含 operator==,但 Visual c++ 包含 (msdn.microsoft.com/en-us/library/8ww0haah.aspx) 它在标准中,第 21.2 节。 哇。我错过了主文件中的 include 。我想它太晚了(这里是凌晨 2 点)继续写代码。 == 在 include 语句之后起作用。【参考方案3】:

std::istreambuf_iterator 的引用很奇特,因为您显示的代码中没有任何内容可以证明这一点——您能否向我们展示Node 以及在一个最小的失败示例中影响到此的任何其他代码?试图从非常部分的代码和错误消息中证明问题非常像拔牙......!-)

【讨论】:

【参考方案4】:

这看起来不错,我看不到std::istreambuf_iterator 是如何进入图片的...

您可能需要调整的一件事是将 const T&amp; 而不是 T 作为您的方法的参数,例如

  Node(const T& d, Node<T> * l = NULL);
  void data(const T& d);

  int List<T>::locate(const T& n) const  ...

实际问题是什么,肯定有其他事情发生。

【讨论】:

【参考方案5】:

开始删除代码,直到它再次起作用。一些错字或流氓宏或冲突的命名空间搞砸了。

这会自己编译吗?

string data = "bla";
Node<string> p("bla");
bool b = p.data() == data;

(每个 C++ 程序员都应该做一个 cout

【讨论】:

以上是关于在 C++ 的模板中使用运算符的主要内容,如果未能解决你的问题,请参考以下文章

尝试在模板类中重载 / 运算符的 C++ 错误

使用 C++ 概念重载不同模板类型的运算符

重载 [] 和 = 运算符以在 C++ 中接受我的模板类的值

C++模板函数定义中的“&”运算符

如何为从C++中的模板继承的类重载赋值运算符

模板类中的 c++ 赋值运算符实现