使用一个参数调用重载函数,但我认为我传递了两个
-
21-09-2019 - |
题
我最近重构了这样的代码(MyClass
到 MyClassR
).
#include <iostream>
class SomeMember
{
public:
double m_value;
SomeMember() : m_value(0) {}
SomeMember(int a) : m_value(a) {}
SomeMember(int a, int b)
: m_value(static_cast<double>(a) / 3.14159 +
static_cast<double>(b) / 2.71828)
{}
};
class MyClass
{
public:
SomeMember m_first, m_second, m_third;
MyClass(const bool isUp, const int x, const int y)
{
if (isUp)
{
m_first = SomeMember(x);
m_second = SomeMember(y);
m_third = SomeMember(x, y);
}
else
{
m_first = SomeMember(y);
m_second = SomeMember(x);
m_third = SomeMember(y, x);
}
}
};
class MyClassR
{
public:
SomeMember m_first, m_second, m_third;
MyClassR(const bool isUp, const int x, const int y)
: m_first(isUp ? x : y)
, m_second(isUp ? y : x)
, m_third(isUp ? x, y : y, x)
{
}
};
int main()
{
MyClass a(true, 1, 2);
MyClassR b(true, 1, 2);
using namespace std;
cout.precision(10);
cout
<< "a:" << endl
<< "\tfirst: " << a.m_first.m_value
<< "\tsecond: " << a.m_second.m_value
<< "\tthird: " << a.m_third.m_value << endl;
cout
<< "b:" << endl
<< "\tfirst: " << b.m_first.m_value
<< "\tsecond: " << b.m_second.m_value
<< "\tthird: " << b.m_third.m_value << endl;
return 0;
}
- 什么错误,
- 为什么可以编译(用VC6测试 以及 VC9 警告级别 4:没有投诉)和
- 正确的做法是什么?
我(假设)我已经有了所有这些答案,但我认为这是一个值得分享的有趣问题。
更新
扩展代码,因此可以“复制、粘贴和执行”。VC9也没有给我任何抱怨,所以 VC6 不是这里的问题。
为了完整起见,输出为:
a:
first: 1 second: 2 third: 1.054069532
b:
first: 1 second: 2 third: 1.004499999
解决方案
我不确定您到底期望什么,但让我们开始......
首先,放弃 VC6。 严重地。 使用它是一个巨大的问题,因为它不符合标准并且排除了很多选择。正确使用它就像玩俄罗斯轮盘赌。
你的构造函数
m_third
并没有按照你的想法去做。您不能编写这样的条件表达式:“几个参数”无效 表达 在 C++ 中,条件运算符适用于表达式。代码可以编译,因为它仍然是 正确的, ,它只是不做你想做的事。它不使用“几个参数”,而是评估序列点运算符(
,
)这只是需要 最后的 表达式的值,因此您的条件实际上相当于:isUp ? y : x
正确的方法是使用 二 条件句:
m_third(isUp ? x : y, isUp ? y : x)
第三个构造函数
SomeMember
是错误的,该值可能会溢出,产生负值——我非常怀疑这就是你想要的。
其他提示
m_third(isUp ? x, y : y, x)
这看起来是错误的。首先 x
是一个毫无意义的表达式,因为它没有副作用并且结果不被使用,那么 :
具有相同的价值和副作用,所以 ?:
可以作为之前的表达式消除 ?
也没有副作用。
m_third(y, x)
但现在它并没有做原始代码所做的事情......这是错误吗?
错误是什么正确的方法?
我猜你的意图是展示逗号运算符与三元 ? 组合的某种天真的用法,也许隐藏着一些聪明且意想不到的运算符优先级陷阱,但我认为代码绝对是人为的。如果这是重点,那么我会说“正确的做法”是不要使用 C++ 或在使用它之前先学习它。是的,它有许多看起来像“怪癖”的构造,您可以创建许多编译器接受的看起来奇怪的代码。通过使用 C++,我想说您应该了解这些工具。
为什么编译不了
因为它不包含错误,并且是正确的 C++ 代码,没有歧义。