この例を考えてみ検出:short
option_s
は、一時オブジェクトを使用してint
に変換される:がCONST参照の暗黙的型変換
#include <iostream>
struct Thing
{
Thing(int const& ref) : ref(ref) {}
int const& ref;
};
int main()
{
int option_i = 1;
short option_s = 2;
Thing thing_i(option_i);
Thing thing_s(option_s);
std::cout << thing_i.ref << "\n"; // 1
std::cout << thing_s.ref << "\n"; // 2
option_i = 10;
option_s = 20;
std::cout << thing_i.ref << "\n"; // 10
std::cout << thing_s.ref << "\n"; // 2 <<< !!!
}
、私はこのケースでWHYを理解します。その一時的な参照は、次いで
// Thing thing_s(option_s);
int __temporary = option_s;
Thing thing_s(__temporary);
に相当即ち、コンストラクタThing::Thing
に渡され、違いを見つけることは非常に難しいしかし、これは多くの場合、所望されないかもしれません。 この場合、テンポラリはまだ少なくとも生きていますが、 ですが、これは一時的なダンピングリファレンスとなることもあります。
このようなconst-reference-to-temporary caseを検出する方法(設計パターン、gccコンパイラオプション、静的解析ツールなど)を知っていますか?
このようなケースを検出するためにconst-correctnessを犠牲にしますか?
あなたのオプションはおそらく最適ですが、SFINAE経由でコンストラクタを削除することもできます。コンストラクタをテンプレート化し、 'enable_if'を使ってそれが' int'であることを確認します。 –
@CrazyEddie:それを行う方法は複数あります。私はこのアプローチが最も清潔であることを知ります。また、呼び出すコンストラクタ/関数が削除されたことを示すため、「禁止された」型が認識されます。そして、コンパイラはより多くのオーバーロードを検索することを止めます。それは**フェイル・ファースト**アプローチになります。 – Nawaz
@CrazyEddie:明示的に削除すると良いエラーメッセージが表示されますが、コンストラクタがないと非常に難解かもしれません。 –