重写<<运营商无法识别

时间:2016-12-11 18:19:56

标签: c++ operator-overloading template-classes

我正在尝试覆盖<<运算符,但似乎编译器无法识别我的实现,而是尝试将其解释为位移。 我已尝试使用参数类型(const T&T&Tconst T)无效。

#pragma once

template<typename T> class AbstractStack
{
    public:
        virtual bool Push(const T &) = 0;
}

template <typename T> class ArrayStack : public AbstractStack <T>
{
    public:
        bool Push(const T&) {
            ....
        }
}

template <typename T> bool operator<<(const AbstractStack<T>* &, const T&) {
    return stack->Push(item);
}


int main() {
    AbstractStack<int> *stack = new ArrayStack<int>(5);
    int a = 2;
    stack << a; // <<-- compiler error
    return 0;
}

报告的错误是:

Error (active)      expression must have integral or unscoped enum type Lab10   
Error   C2296   '<<': illegal, left operand has type 'AbstractStack<int> *' 

如果我将作为一个值的同一个操作符定义为一个值,它就可以工作......

2 个答案:

答案 0 :(得分:3)

当重载运算符时,至少有一个参数必须是类或枚举类型 - 基本上这允许/限制您重载自定义类型(用户定义的类型)。

来自cppreference;

  

当运算符出现在表达式中,并且其操作数中至少有一个具有类类型或枚举类型时,则使用重载决策来确定要在其签名与其匹配的所有函数中调用的用户定义函数以下...

这是有道理的,因为它不允许你重载内置类型; 在这种情况下,指针和整数作为参数

正如您在问题中已经提到的那样,解决方案是通过引用获取您的第一个参数;

template <typename T>
bool operator<<(AbstractStack<T> &, const T&)
{ //...

考虑到您要使用的抽象基类,您可以调查使用std::shared_ptr来帮助管理资源并使用&#34;指针&#34;在重载运算符(虽然它将是一个智能指针);

template <typename T>
bool operator<<(std::shared_ptr<AbstractStack<T>>&, const T&)
{
  return stack->Push(item);
}

int main() {
  std::shared_ptr<AbstractStack<int>> stack = std::make_shared<ArrayStack<int>>(5);
  int a = 2;
  stack << a;
  return 0;
}

答案 1 :(得分:2)

正如其他人所说,重载任何内置运算符需要用户定义类型的对象;指针不起作用。解决方案是使用对象而不是指针:

template <typename T> bool operator<<(AbstractStack<T>&, const T&) {
    return stack.Push(item);
}

然后用一个对象调用它。你已经证明从免费商店分配的代码没有充分的理由;只需创建一个自动对象:

int main() {
    ArrayStack<int> stack(5);
    int a = 2;
    stack << a;
    return 0;
}