5

この質問からの議論をフォローアップして、ネイティブ C++ を使用している場合、使用している std::string 実装がコピー オン ライト (COW)を利用しているかどうかをプログラムでどのように判断するのか疑問に思っていました。

私は次の機能を持っています:

#include <iostream>
#include <string>

bool stdstring_supports_cow()
{
   //make sure the string is longer than the size of potential
   //implementation of small-string.
   std::string s1 = "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789";
   std::string s2 = s1;
   std::string s3 = s2;

   bool result1 = (&s1[0]) == (&s2[0]);
   bool result2 = (&s1[0]) == (&s3[0]);

   s2[0] = 'X';

   bool result3 = (&s1[0]) != (&s2[0]);
   bool result4 = (&s1[0]) == (&s3[0]);

   s3[0] = 'X';

   bool result5 = (&s1[0]) != (&s3[0]);

   return result1 && result2 &&
          result3 && result4 &&
          result5;
}

int main()
{
  if (stdstring_supports_cow())
      std::cout << "std::string is COW." << std::endl;
   else
      std::cout << "std::string is NOT COW." << std::endl;
   return 0;
}

問題は、true を返す C++ ツール チェーンが見つからないように見えることです。COW が std::string にどのように実装されているかについての私の仮定に欠陥はありますか?

更新: kotlinski のコメントに基づいて、関数内の data() への writeble 参照の使用を変更しました。一部の実装では「true」を返すようになりました。

bool stdstring_supports_cow()
{
   //make sure the string is longer than the size of potential
   //implementation of small-string.
   std::string s1 = "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789";
   std::string s2 = s1;
   std::string s3 = s2;

   bool result1 = s1.data() == s2.data();
   bool result2 = s1.data() == s3.data();

   s2[0] = 'X';

   bool result3 = s1.data() != s2.data();
   bool result4 = s1.data() == s3.data();

   s3[0] = 'X';

   bool result5 = s1.data() != s3.data();

   return result1 && result2 &&
          result3 && result4 &&
          result5;
}

注: N2668: "Concurrency Modifications to Basic String"によると、今後の C++0x 標準では、basic_string から COW オプションが削除されます。それを提起してくれた James と Beldaz に感謝します。

4

2 に答える 2

8

を使用&s1[0]してアドレスを取得することは、あなたが望むものではなく[0]、書き込み可能な参照を返し、コピーを作成します。

代わりに data() を使用すると、const char* が返され、テストに合格する可能性があります。

于 2010-12-21T04:08:15.630 に答える
0

コピー オン ライト パラダイムは、いつ書き込みを行っているかを知ることに依存しています。これは、オブジェクトが書き込み可能な参照を返すたびに発生します。

文字列への const 参照を使用する場合、クラスがデータへの const 参照を返すときにコピーを無効にするように特化されていれば、アドレスを比較できる場合があります。

于 2010-12-21T04:14:27.867 に答える