C++ 接受错误的 return 类型
C++ accepts wrong return-type
我有以下代码,在我看来,它不应该编译:
(在class Vector
中(不是 std::vector
,而是我自己定义的Vector
):
Vector operator*(double factor)
{
// some element-wise multiplication here
return factor;
}
我将此运算符定义为 return a Vector
,但在方法内部我 return a double
.
我还 not 在 class.
中定义了任何 隐式转换运算符
我认为这显然是无效的,但 gcc 很高兴地编译了它,没有任何抱怨。
我的第一反应是向 gcc 提交缺陷报告,但我想我之前会在这里问..
我是否遗漏了一些可以解释为什么编译器认为此代码有效的内容?
(如果相关,c++-standard 设置为 c++17)
关于 Vector
class 的更多信息:(即,我包括所有已声明的构造函数和运算符,因为其他命名函数不应导致此问题):
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);
}
此答案基于收到的评论:
非显式转换运算符并不是最初类型错误的 return 值可能“变成”函数签名所需类型的唯一方式。
构造函数
Vector(size_t dimension);
以一个数值作为参数,它本身不是double
,而是long unsigned int
,但double
可以转换成double
。
所以发生的是 double factor
首先转换为 long unsigned int
,然后使用构造函数 Vector(size_t dimension);
隐式构造 Vector
。
然后 returned.
作为此构造结果的对象
因此,从不违反语言规则的角度来看,这是有效代码,编译器绝对没有做错任何事情。
如果不需要这种行为,则有问题的构造函数应标记为 explicit
,如下所示:
explicit Vector(size_t dimension);
如果有多个构造函数接受一个类型的参数,double
可以转换为该类型,或者其第一个参数满足该要求,所有其他参数都是可选的,例如:
Vector(int a, char b = 'c');
它们也必须标记为 explicit
,但在那种情况下,编译器可能会抱怨,因为它无法推断出要调用哪个构造函数。
我有以下代码,在我看来,它不应该编译:
(在class Vector
中(不是 std::vector
,而是我自己定义的Vector
):
Vector operator*(double factor)
{
// some element-wise multiplication here
return factor;
}
我将此运算符定义为 return a Vector
,但在方法内部我 return a double
.
我还 not 在 class.
中定义了任何 隐式转换运算符我认为这显然是无效的,但 gcc 很高兴地编译了它,没有任何抱怨。
我的第一反应是向 gcc 提交缺陷报告,但我想我之前会在这里问..
我是否遗漏了一些可以解释为什么编译器认为此代码有效的内容?
(如果相关,c++-standard 设置为 c++17)
关于 Vector
class 的更多信息:(即,我包括所有已声明的构造函数和运算符,因为其他命名函数不应导致此问题):
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);
}
此答案基于收到的评论:
非显式转换运算符并不是最初类型错误的 return 值可能“变成”函数签名所需类型的唯一方式。 构造函数
Vector(size_t dimension);
以一个数值作为参数,它本身不是double
,而是long unsigned int
,但double
可以转换成double
。
所以发生的是 double factor
首先转换为 long unsigned int
,然后使用构造函数 Vector(size_t dimension);
隐式构造 Vector
。
然后 returned.
因此,从不违反语言规则的角度来看,这是有效代码,编译器绝对没有做错任何事情。
如果不需要这种行为,则有问题的构造函数应标记为 explicit
,如下所示:
explicit Vector(size_t dimension);
如果有多个构造函数接受一个类型的参数,double
可以转换为该类型,或者其第一个参数满足该要求,所有其他参数都是可选的,例如:
Vector(int a, char b = 'c');
它们也必须标记为 explicit
,但在那种情况下,编译器可能会抱怨,因为它无法推断出要调用哪个构造函数。