Google C ++スタイルガイドには、演算子のオーバーロードに関するセクションがあり、奇妙なステートメントがあります。
オーバーロードには、驚くべき影響もあります。たとえば、をオーバーロードするクラスを前方宣言することはできません
operator&
。
これは正しくないようで、GCCで問題が発生する原因となるコードを見つけることができませんでした。その声明が何を指しているのか誰か知っていますか?
Google C ++スタイルガイドには、演算子のオーバーロードに関するセクションがあり、奇妙なステートメントがあります。
オーバーロードには、驚くべき影響もあります。たとえば、をオーバーロードするクラスを前方宣言することはできません
operator&
。
これは正しくないようで、GCCで問題が発生する原因となるコードを見つけることができませんでした。その声明が何を指しているのか誰か知っていますか?
標準の 5.3.1 には、「不完全な型のオブジェクトのアドレスは取得できますが、そのオブジェクトの完全な型が operator&() をメンバー関数として宣言するクラス型である場合、動作は未定義です (および no診断が必要です)。」
私もこれを知りませんでしたが、別の投稿者が指摘したように、コンパイラが誤ったコードを生成する原因になることは容易にわかります。
私もそれについて聞いたことがありませんでしたが、これはオーバーロードの前後の同じコードに対して潜在的に混乱する結果をもたらします:
#include <iostream>
class Foo;
void bar (Foo& foo) {
std::cout << &foo << std::endl;
}
class Foo {
public:
bool operator & () { return true; }
};
void baz (Foo& foo) {
std::cout << &foo << std::endl;
}
int main () {
Foo foo;
bar(foo);
baz(foo);
return 0;
}
出力:
0x7fff092c55df
1
とにかくそれをしない理由は他にもありますが、アドレスのオーバーロードは、stlや多くの一般的なコードではうまく機能しません。
声明は正確ではないと思います。他の答えのように、私はここで推測しています。まず、二項演算子ではなく単項演算子&を参照していると仮定します。あれは:
int x = 5;
int* p = &x; // unary &
if (x & 1) // binary &
必要なクラスを前方宣言できます。ただし、クラスが単項演算子&をオーバーロードし、それらのオブジェクトの1つへのポインターで単項演算子&を呼び出すと、一貫性のない動作が発生する可能性があります(アドレスを取得するだけの場合もあれば、オーバーロードされたメソッドを呼び出す場合もあります)。これは、デバッグがほぼ不可能なものに簡単に変わる可能性があります。
fizzerが実際に標準を見て、推測しなかったのはうれしいです。
operator& をオーバーロードできるため、boost ライブラリは便利なテンプレート addressof()を提供して、クラスの実際のアドレスを見つけます。operator& をオーバーロードすることをお勧めしているわけではありませんが、必要に応じてヘルプを利用できます。
コメントを説明するために編集:
これは推測ですが、前方宣言を行う主な理由の1つは、そのクラスへのポインターを宣言できるようにすることです。コンパイラーは、定義(ポインターのサイズなど)を取得する前に、クラスについて仮定する必要があります。
Tのoperator&をオーバーロードすることでT *のサイズを変更することは可能ですか?(編集:コメンテーター-そして私はそうではないと思います)-しかし
演算子のオーバーロードによってどのような仮定に違反しますか?-クラスをどのように変更しますか?
これが1つの方法です。
私は書くことができます:
class A;
void f(A& x) {
A* xPointer = &x;
}
これは、operator&()がオーバーロードされている場合よりもオーバーロードされている場合に新しい意味を持ち、コンパイラーはそのためのコードを生成できると考えるかもしれませんが、それは間違っています。
もちろん、クラスを前方宣言できますが、ルールは明らかに、クラスがオーバーロードする場所で「すべきではない」という立場をとっていますoperator&
。
同様のルールは、他のコーディング標準にも存在します。たとえば、JSF(pdf)ルール 159operator&
ではオーバーロードしてはならないことが規定されています。