【问题标题】:C++ accepts wrong return-typeC++ 接受错误的返回类型
【发布时间】:2020-07-12 20:02:14
【问题描述】:

我有以下代码,在我看来,它不应该编译: (class Vector不是std::vector,而是我自己定义的Vector):

Vector operator*(double factor)
{
  // some element-wise multiplication here
  return factor;
}

我将这个运算符定义为返回一个Vector,但在方法内部我返回一个double

我还没有在类中定义了任何隐式转换运算符

我认为这显然是无效的,但 gcc 很高兴地编译了它,完全没有任何抱怨。

我的第一个反应是向 gcc 提交缺陷报告,但我想我会在此之前问...

我是否遗漏了一些可以解释为什么编译器认为此代码有效的内容?

(如果相关,c++-standard 设置为 c++17)

关于Vector 类的更多信息:(即,我包括所有声明的构造函数和运算符,因为其他命名函数不应导致此问题):

class Vector {
public:
  Vector(std::vector<double> values);
  Vector(size_t dimension, double value);
  Vector(size_t dimension);

  void operator*=(double factor);
  void operator*=(Vector const& factor);

  friend Vector operator-(Vector const& a, Vector const& b);
  friend Vector operator+(Vector const& a, Vector const& b);
  friend Vector operator*(Vector const& a, Vector const& b);

  Vector operator*(double factor);
  double& operator[](size_t i);

  friend std::ostream& operator<<(std::ostream& stream, Vector const& v);
}

【问题讨论】:

  • 没有看到Vector的定义很难说代码是否有效。
  • minimal reproducible example - 没有发生
  • 猜测 Vector 有一个非显式的单参数构造函数,它接受一个数值,例如:godbolt.org/z/EcTvGo
  • “我的第一反应是向 gcc 提交缺陷报告”,这应该是你最后的反应。
  • 您应该将一个构造函数更改为explicit Vector(size_t dimension);

标签: c++ gcc operator-overloading implicit-conversion


【解决方案1】:

此答案基于收到的 cmets:

非显式转换运算符并不是最初具有错误类型的返回值可能“变成”函数签名所需类型的唯一方式。 构造函数

Vector(size_t dimension);

以一个数值为参数,它本身不是double,而是long unsigned int,但double可以转换成那个。

所以发生的情况是double factor 首先被转换为long unsigned int,然后使用构造函数Vector(size_t dimension); 隐式构造Vector。 然后返回作为此构造结果的对象。

因此,从不违反语言规则的意义上说,这是有效的代码,编译器在这里肯定没有做错任何事情。

如果不希望出现这种行为,则应将相关构造函数标记为 explicit,如下所示:

explicit Vector(size_t dimension);

如果有多个构造函数采用 double 可以转换成的类型的一个参数,或者它们的第一个参数满足该要求而所有其他参数都是可选的,例如:

Vector(int a, char b = 'c');

它们也必须标记为explicit,但在这种情况下,编译器很可能会抱怨,因为它无法推断要调用哪个构造函数。

【讨论】:

    猜你喜欢
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 2021-04-15
    相关资源
    最近更新 更多