オーバーロードされた関数が 1 つのパラメーターで呼び出されましたが、2 つのパラメーターを渡したと思っていました
-
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)
の 3 番目のコンストラクター
SomeMember
それが間違っていると、値がオーバーフローして負の値が生成される可能性があります。それがあなたが望むものであるかどうかは非常に疑わしいです。
他のヒント
m_third(isUp ? x, y : y, x)
これがあることを間違って見えます。最初x
は、副作用がなく、結果が使用されないよう:
も副作用を持たない前?:
式としてelimintatedすることができるので、その後?
の双方が同じ値と副作用が無意味式でありますます。
m_third(y, x)
しかし、今では元のコードが何を行っていない...これは誤りです?
エラーとは何ですか それを行うための正しい方法は何ですか?
私はあなたの意図は?、おそらく隠されたいくつかの巧妙な予期せぬ演算子の優先順位の落とし穴がある三元との組み合わせでカンマ演算子の素朴な使用方法のいくつかの種類を示すことであるが、私はコードは絶対に人工的だと思うことを推測します。これがポイントである場合、私は「それを行うための正しい方法を」言うよりも、C ++を使用するか、それを最初に使用する前にそれを学ばないです。はい、それは「癖」のように見えるかもしれません、あなたは、コンパイラによって受け入れられる不思議な格好多くのコードを作成することができ、多くの構造を持っています。 Cを使用することにより++私は、あなたがツールを知っていると想定されていると言うでしょう。
なぜコンパイルんさ。
は、それがエラーを含んでいないので、それはない曖昧で正しいC ++コードである。