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

Posted

技术标签:

【中文标题】尝试在模板类中重载 / 运算符的 C++ 错误【英文标题】:C++ Errors trying to overload the / operator in a templated class 【发布时间】:2014-05-10 03:22:28 【问题描述】:

我正在尝试为我创建的模板类重载“+”、“-”和“/”运算符。 + 和 - 运算符完美运行,但 / 运算符重载给了我错误。

我正在使用 Visual Studio 2013

//Set.h 
#pragma once
#include <iostream>
#include <vector>
using namespace std;

template<class T>
class Set
   
    friend Set<T> operator+ <> (const Set& left, const Set& right);  //works
    friend Set<T> operator- <> (const Set& left, const Set& right);  //works
    friend Set<T> operator/ <> (const Set& left, const Set& right);  //does not

public:
    Set(int n)
    
        numItems = n;
        setItems();
    
    Set()
    
        numItems = 0;
        setItems();
    
    ~Set();
    void setItems();
    void output();
private:
    int numItems;
    vector<T> set;
;

我想重载 / 运算符以确定intersection of two sets

定义:

    //---------------- Overload intersection -----------------
template<class T>
Set<T> operator/(const Set<T>& left, const Set<T>& right)

    bool putin = false;
    Set<T> quotient;

    // loops through left Set
    for (int i = 0; i < left.set.size(); i++)
    
        for (int j = 0; j < right.set.size(); j++)
            //loops through right set
        
            //checks if the item in left is in right set
            // if it is, PUT IT IN the new set
            if (left.set[i] == right.set[j])
                putin = true;
        
        if (putin)
            quotient.set.push_back(left.set[i]);
        putin = true;
    

    return quotient;
 

这是我遇到的错误

Error 1 error C2143: syntax error : missing ';' before '&lt;'

Error 2 error C2460: '/' : uses 'Set&lt;T&gt;', which is being defined

Error 3 error C2433: '/' : 'friend' not permitted on data declarations

Error 4 error C2238: unexpected token(s) preceding ';'

Error 5 error C2365: '/' : redefinition; previous definition was 'data variable'

Error 6 error C2904: '/' : name already used for a template in the current scope

Error 7 error C2460: '/' : uses 'Set&lt;int&gt;', which is being defined

【问题讨论】:

【参考方案1】:

这很棘手,它被 C++ FAQ 条目覆盖。

我无法准确解释为什么您的编译器会出现错误。但是您的所有运算符的代码都不正确:如常见问题解答中所述,编译器认为您正在尝试 friend 非模板函数,但这不起作用,因为函数确实需要是模板函数才能接受Set&lt;T&gt;

FAQ 建议的解决方案是先声明模板函数,然后再将它们加为好友:

template<typename T> class Set;

template<typename T>
Set<T> operator+ (const Set<T>& left, const Set<T>& right);
template<typename T>
Set<T> operator- (const Set<T>& left, const Set<T>& right); 
template<typename T>
Set<T> operator/ (const Set<T>& left, const Set<T>& right); 

template<class T>
class Set
   
    friend Set<T> operator+ <> (const Set<T>& left, const Set<T>& right);
    friend Set<T> operator- <> (const Set<T>& left, const Set<T>& right);
    friend Set<T> operator/ <> (const Set<T>& left, const Set<T>& right);

请注意,您需要使用Set&lt;T&gt;,而不仅仅是原始代码中的Set。 这是可行的,因为现在编译器知道我们在谈论函数模板,因此它可以在 friend 行中识别它们。

另一个可能的解决方案是,没有函数的前向声明:

template<class T>
class Set
   
template<class U>
friend Set<U> operator / (const Set<U>& left, const Set<U>& right); 
template<class U>
friend Set<U> operator+ (const Set<U>& left, const Set<U>& right);
template<class U>
friend Set<U> operator- (const Set<U>& left, const Set<U>& right);
public:
// ...

您明确地将模板函数称为朋友。我不完全确定第二种方法是个好主意。

如果您的运算符具有“正常”语义,那么也许您可以一起避免这个问题,但根本不使用friends。如果你定义了成员函数operator+=operator-=operator/=,它们对*this进行操作,那么在类之外声明其他操作符很简单,它们无需成为朋友就可以委托给这些函数:

template<typename T> 
Set<T> operator+ (Set<T> a, Set<T> const &b  return a += b; 

【讨论】:

以上是关于尝试在模板类中重载 / 运算符的 C++ 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在具有动态大小数组的模板类中重载 operator=

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

逆向第十九讲——类继承和成员类运算符重载模板逆向20171211

如何重载模板类的“新”运算符?

枚举类中的 c++ 运算符重载

操作符(运算符)重载注意事项(含模板类中<<;;重载)