3

我试图覆盖<<运算符,但编译器似乎无法识别我的实现,而是试图将其解释为位移。我已经尝试过使用参数类型 ( const T&, T&, T, const 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> *' 

如果我将作用于类的相同运算符定义为值,它就可以工作......

4

2 回答 2

3

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

来自cppreference

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

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

正如您在问题中已经说过的那样,解决方案是通过引用来获取您的第一个论点;

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

鉴于您要使用的抽象基类,您可以研究使用std::shared_ptr来帮助管理资源并在重载运算符中使用“指针”(尽管它将是一个智能指针);

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;
}
于 2016-12-11T18:26:21.380 回答
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;
}
于 2016-12-11T18:31:03.230 回答