0

SOに関する以前の質問 ( 1および2std::move )は、a の要素に適用するstd::initializer_listと UB につながる可能性があることを示唆しているようです。実際、std::initializer_list反復子は const 要素を参照するため、効果的な移動を妨げます。その理由は、コンパイラinitializer_list の基になる配列を格納するために静的な読み取り専用メモリを使用する可能性があるためです。

この見解は限定的すぎると思います。ここにいる専門家が同意するかどうか知りたいです。IMO、次のコードは読み取り専用ストアを使用できない可能性があります。

void attempt_move(std::initializer_list<std::string> list) {
  // must use const std::string &. Can't move.
}
int main(int argc, char *argv[])
{
  if(argc >= 4)  
    attempt_move({ argv[1], argv[2], argv[3] }); 
}

私の知る限り、読み取り専用ストアは前に初期化する必要があり、その時点ではパラメーターがわからないため、基になるstd::string配列は読み取り専用ストアに存在することはできません。実際、C++11 標準では次のように述べられています。「[注: 同じイニシャライザを持つ明示的な配列がそのように割り当てられる場合、実装は読み取り専用メモリに配列を自由に割り当てることができます。—注記終了]」. これは、「同じ初期化子を持つ明示的な配列」を読み取り専用に割り当てることができない 1 つのケースのようです。したがって、おそらく自動ストレージがあります。mainargv

そうであれば、 の const イテレータが原因で文字列オブジェクトを移動する機会が失われているようですstd::initializer_list。回避策はありますか?

4

1 に答える 1

0

const_cast基になるオブジェクトが修飾されていない場合は、修飾を解除できますがconst、参照のみが修飾されています。

ただし、const修飾は、物理 ROM に静的に格納されることと必ずしも同じではありません。ほとんどの場合、コンパイラは、オブジェクトが誰にも変更されないことが安全であると単純に信じています。

はい、未定義の動作です。そして、これは の重大な欠点と見なされinitializer_listます。C++17 で修正されることを願っています。

はい、移動がこれらの要素に発生する唯一のことである場合は、おそらくそれを回避できます。実際initializer_list、太陽の下でのほとんどすべての安全なユースケースをカバーしています.

于 2013-09-16T06:19:38.177 に答える