2

コンストラクターから一時的なアドレスを取得することについて不平を言うコンパイラーとそうでないコンパイラーがあるのはなぜですか?

例えば:

WriteLine(&String8("Exception"));

不平を言っているコンパイラがそのアドレスをスタックに保存しておらず、警告を無視すると爆発すると思います。それを1行で機能させる方法はありますか?アドレスを返すクラスの静的メソッドが最善/唯一の方法ですか? うーん、ポインタを返す String8 クラスの静的メソッドは、String8 クラスをレジスタに保存してから WriteLine() で使用するため、機能するとは思いません。

4

2 に答える 2

5

あなたが与えるサンプルコード、

WriteLine(&String8("Exception"));

型がカスタム アドレス演算子を定義しない限り、標準 C++ としては無効です。String8


あなたが尋ねる、

「コンストラクターからテンポラリーのアドレスを取得することに不平を言うコンパイラーとそうでないコンパイラーがあるのはなぜですか?」

C++ 標準では、組み込みのアドレス演算子を使用して一時的なアドレスを取得することはできないと規定されているため、一部のコンパイラは文句を言います。

C++11 §5.3.1/3 :
「単項演算子の結果は、&そのオペランドへのポインターです。オペランドは、左辺値または修飾 IDでなければなりません。

Visual C++ などの一部のコンパイラは、言語拡張機能としてアドレスを取得する機能を提供するため、文句を言いません。


ユーザー定義型は、カスタム アドレス演算子を定義できることに注意してください。したがって、あなたの場合String8typeによって異なります。コンパイラと同様に。


あなたはさらに尋ねます、

「それを 1 行で機能させる方法はありますか?」

はい、アドレス演算子を定義できます。しかし、それは良い考えではありません。まず第一に、標準ライブラリなどで問題が発生するだけであり、第二に、その必要性は非常にまれです。

そのような解決策を真剣に検討した 1 つのケース、つまり、COM スマート ポインターを外部引数として渡すケースだけを思い出すことができます。アドレス演算子を定義する代わりに、名前付きメソッドを定義しました。それははるかに明確で、他のものを妨げません。

于 2013-01-05T08:15:28.120 に答える
2

コードは完全に有効です ( MSVC 上)。そして、あなたは赤いニシンとして警告を無視することができます.

考慮すべき 2 つの問題があります。

  1. 標準では許可されていない一時的な (別名: rvalue )のアドレスを取得する&
  2. 一時的なアドレスの有効期間が取得されます。

カウンターの問題 1:
MSVC では、拡張機能を介して一時的なアドレスを取得できます。したがって、一時的なアドレスを取得すると、少なくともあなたの場合はコンパイルされます(MSVCの礼儀)。

カウンターの問題 2:さらに、少なくとも式が終了するまで
一時的なものは存続することが保証されます。正確には、String8("Exception")from から戻った直後に式が終了することに注意してください( call の末尾のセミコロン)。したがって、それは完全に有効です。この場合、警告はおせっかいと見なすことができます。WriteLine();

C++03 標準 §12.2/3:

一時オブジェクトは、それらが作成されたポイントを (レキシカルに) 含む完全な式 (1.9) を評価する最後のステップとして破棄されます。

于 2013-01-05T08:04:07.747 に答える