Вопрос об использовании строки:: подкачка () с временными файлами

Следующий сегмент демонстрирует мою проблему: (ошибка компиляции на GCC)

stringstream ss;
string s;
ss << "Hello";

// This fails:
// s.swap(ss.str());

// This works:
ss.str().swap(s);

Моя ошибка:

constSwap.cc:14: error: no matching function for call to 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >::swap(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
basic_string.tcc:496: note: candidates are: void std::basic_string<_CharT, _Traits, _Alloc>::swap(std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]

В то время как я понимаю, что ул. () в stringstream возвращает временный файл, это не имеет смысла и не было сразу очевидно, что я должен был называть подкачку на временном файле с локальной переменной как параметр вместо моего первого инстинкта.

Очевидно прямое присвоение работает лучше, и более новые стандарты C++ имеют семантику перемещения, которая прекрасна, но они не доступны для моей реализации.

Visual Studio не дает эту проблему из-за него ослабляемый о стандарте C++. Я отчасти уже понимаю целую ссылку константы на временную вещь (который я принимаю, причина моих ошибок компиляции).

Мой вопрос: кто-либо может объяснить мне, если это - единственное решение, и, возможно, объясните мне, как думать об этом в будущем, таким образом, я могу определить и работать вокруг подобных проблем?

(Если ни у кого нет большого понимания, я, по крайней мере, отправляю это здесь для людей с подобными проблемами),

5
задан Marius 12 July 2010 в 21:53
поделиться

3 ответа

После использования идиомы swap-with-temporary достаточное количество раз, со строками типа

std::vector<int>().swap(v); // clear and minimize capacity

или

std::vector<int>(v).swap(v); // shrink to fit

это не кажется таким уж неуместным. Это нормально вызывать swap как функцию-член временного объекта. Конечно, не так идиоматично использовать swap для заполнения строки, построенной по умолчанию, вместо использования конструктора копирования, как уже упоминалось.

2
ответ дан 13 December 2019 в 22:01
поделиться

Вы не можете привязать временную ссылку к неконстантной ссылке. По этой причине временное значение, возвращенное из ss.str () , не может быть передано в std :: string :: swap , который ожидает изменения своего параметра (для этого он принимает свой аргумент, используя неконстантный & ).

Вторая версия работает, поскольку вы вызываете разрешенную функцию-член временного объекта.

Но почему вы вообще хотите делать свопинг? Обычно достаточно простого:

std::string s(ss.str());

. Это не менее эффективно, чем своп (по крайней мере, в C ++ 0x с семантикой перемещения), но в то же время намного более читабельно.

7
ответ дан 13 December 2019 в 22:01
поделиться

Причина, по которой вы не можете передать временный аргумент в качестве аргумента swap , заключается в том, что аргумент передается по неконстантной ссылке. А временные объекты могут быть связаны только константными ссылками. Это распространяется на §8.5.3, с соответствующим указанием в параграфе 5, втором маркере:

§8.5.3 Ссылка на тип «cv1 T1» инициализируется выражением типа «cv2 T2» следующим образом:

  • [первый пункт, здесь не применяется: привязка к неконстантной ссылке]

  • В противном случае ссылка должна быть на энергонезависимый константный тип (т.е. cv1 должен быть константным).

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

§3.10 / 10 Для изменения объекта необходимо lvalue для объекта, за исключением того, что rvalue типа класса также может использоваться для изменения его референта при определенных обстоятельствах. [Пример: функция-член, вызываемая для объекта (9.3), может изменять объект. ]

Логика, которую вы запрашиваете на будущее, заключается в том, что, хотя вы можете изменить временное с помощью его собственных функций, вы не можете передать его функции или методу, которые могли бы его изменить (передать по неконстантной ссылке)

1
ответ дан 13 December 2019 в 22:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: