c++ - operator<<() 由于继承而无法从模板解析

标签 c++ templates compiler-errors operator-overloading c++17

我正在使用一组类,我的主要代码如下所示:

主.cpp

#include "calc.h"

int main() {
    neg_inf nif;
    pos_inf pif;

    limit<double, infinity> l( 3.4, nif, pif, 2.2 )

    std::cout << "value dx  = " << l.value() << '\n'
              << "lower lim = " << l.lower() << '\n'
              << "upper lim = " << l.upper() << '\n'
              << "step_size = " << l.step() << '\n';

    return EXIT_SUCCESS;
}

预期的输出应该是:
value dx  = 3.4
lower lim = -inf
upper lim = inf
step_size = 2.2

这是我的类(class):

计算.h
#pragma once

#include <cmath>
#include <iostream>
#include <limits>
#include <type_traits> 

struct infinity {
protected:
    infinity() = default;
};

struct pos_inf : public infinity {
    constexpr double operator()() { return std::numeric_limits<double>::infinity(); }
};

struct neg_inf : public infinity {
   constexpr double operator()() { return -std::numeric_limits<double>::infinity(); }
};

std::ostream& operator<<( std::ostream& os, const pos_inf& inf );
std::ostream& operator<<( std::ostream& os, const neg_inf& inf );

template<typename dX, class bound>
class limit {
    dX dx;
    bound lowerBound;
    bound upperBound;
    double step_size;

public:
    limit( dX x, bound lower, bound upper, double step = 1 ) :
        dx{ x }, lowerBound{ lower }, upperBound { upper }, step_size { step }
    {}

    dX value() const { return dx; }
    bound lower() const { return lowerBound; }
    bound upper() const { return upperBound; }
    double step() const { return step_size; }
};

计算.cpp
#include "calc.h"

std::ostream& operator<<( std::ostream& os, const pos_inf& inf ) {
    // originally intended to do:
    // return os << inf(); // but fails to compile

    auto v = pos_inf()(); // this works
    return os << v;
}

std::ostream& operator<<( std::ostream& os, const neg_inf& inf ) {
    // same as above...

    auto v = neg_inf()();
    return os << v;
}

然而,在 main.cpp Visual Studio 2017 正在生成此编译器错误:
c:\***\main.cpp(33): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'bound' (or there is no acceptable conversion)
1>        with
1>        [
1>            bound=infinity
1>        ]

基于这行代码:
<< "lower lim = " << l.lower() << '\n'

并且从 l.lower() 失败

但是,如果我主要这样做:
#include "calc.h"

int main() {
    neg_inf nif;
    pos_inf pif;

    std::cout << nif << '\n' << pif << '\n'

    return EXIT_SUCCESS;
}

我得到输出:
-inf
inf

这告诉我我的 operator<<()正在为继承的结构工作,但是当我将它的父类型作为模板参数传递并将派生类型传递给我的 limit 的构造函数时类,operator<<()没有解决。这似乎是一个模棱两可的问题,但我不知道如何解决这个问题。我在这里错过或忽略了什么?

作为这个问题之外的旁注,是否有更优雅的方式来表示 -/+inf ?我在这里使用继承是因为 +- inf不是数字,而是一个概念,它们彼此相似,但指向不同的方向。因此,当我将无穷大类型作为模板参数传递时,我希望能够将下限设置为 -inf,将上限设置为 +inf。我希望绑定(bind)类型是模板,因为我可能想使用整数边界或双边界,例如 [-1,1] 之间或 [0.0,1.0]其中这些都是数字界限。我不确定如何以更优雅的方式表达无限,任何提示或建议将不胜感激。

最佳答案

不要以这种方式重载子类的运算符。使用虚方法进行输出,并使用泛型类型和调用虚方法的重载运算符:

class infinity {
  public:
    virtual ostream &printTo(ostream &o) const = 0;
};
ostream &operator<<(ostream &o,const infinity &i) {
  return i.printTo(o);
}
class neg_inf : public infinity {
  public:
    virtual ostream &printTo(ostream &o) const {
        // do what you want
        return o;
    }
};

关于c++ - operator<<() 由于继承而无法从模板解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56656139/

相关文章:

c++ - -static-libasan 的 undefined symbol 错误

templates - Magento 通过代码获取电子邮件模板

c++ - 复杂类的值类型,或类本身

java - 使用JSSC从串行端口读取。我如何使用输入流

c++ - 使用 QTextEdit 检测用户输入(并将其与应用程序更改区分开来)

c++ - 为命名空间中的类模板重载输出运算符

c++ - 是否可以使用 Clang 3.1 和 VC11 Beta header 编译 C++ 源代码?

javascript - Angular.js 加载、处理并显示通过 REST $resource 获取的动态模板

c - 如何解决此C程序中的类型重定义错误

c++ - undefined reference c++,异常情况