Программно определить, использует ли std :: string механизм Copy-On-Write (COW) - PullRequest
4 голосов
/ 21 декабря 2010

Продолжая обсуждение этого вопроса , мне было интересно, как тот, кто использует нативный C ++, программно определяет, использует ли используемая реализация std :: string Copy- При записи (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;
}

Проблема в том, что я не могу найти цепочку инструментов C ++, где она возвращает true. Есть ли недостаток в моем предположении о том, как COW реализован для std :: string?

Обновление: Основываясь на комментариях Котлински, я изменил использование ссылок на записи для data () в функции, теперь она, похоже, возвращает "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: «Модификации параллелизма для базовой строки» , в следующем стандарте C ++ 0x опция COW будет удалена из basic_string. спасибо Джеймсу и Белдазу за то, что подняли это.

Ответы [ 2 ]

6 голосов
/ 21 декабря 2010

Использование &s1[0] для получения адреса не то, что вам нужно, [0] возвращает доступную для записи ссылку и создаст копию.

Вместо этого используйте data (), возвращает const char *, иВаши тесты могут пройти.

0 голосов
/ 21 декабря 2010

Парадигма копирования при записи зависит от знания, когда вы делаете запись. Это будет происходить всякий раз, когда объект возвращает доступную для записи ссылку.

Если вы работаете с константными ссылками на строки, вы можете сравнить адреса, если класс специализировался на отключении копирования при возврате константной ссылки на данные.

...