Я читал декларацию структурированной привязки на cppreference.com
Я думал, что хорошо разбираюсь в примерах, пока не достиг последнего примера внизу.
#include <set>
#include <string>
#include <iomanip>
#include <iostream>
int main() {
std::set<std::string> myset;
if (auto [iter, success] = myset.insert("Hello"); success)
std::cout << "insert is successful. The value is " <<
std::quoted(*iter) << '\n';
else
std::cout << "The value " << std::quoted(*iter) << " already
exists in the set\n";
}
На первый взгляд все выглядело нормально, но чем больше я смотрел на него, тем меньше я понимал предложение if.
Вверху перечислены возможные формы, перечисленные как:
attr (необязательно) cv-auto ref-operator (необязательно) [идентификатор-список] = выражение;(1)
attr (необязательно) cv-auto ref-operator (необязательно) [идентификатор-список] {выражение};(2)
attr (необязательно) cv-auto ref-operator (необязательно) [идентификатор-список] (выражение);(3)
Мне кажется, что это тип дедукции (1).Но это как-то не имеет смысла для меня, потому что выражение
- выражение, которое не имеет запятой на верхнем уровне (грамматически, выражение-присваивание) и имеет либо массив, либо нетип объединения.Если выражение ссылается на какое-либо из имен из списка идентификаторов, объявление является некорректно сформированным.
, что говорит о том, что объявление неправильно сформировано, если выражение находится в списке идентификаторов.Так что мне кажется, что успех не является частью выражения.Если это так, то
auto [iter, success] = myset.insert("Hello");
назначит только вставленные "Hello"
на iter
, а success
будет чем?!?Наоборот, это нарушит часть выражения.Но он явно компилируется и запускается, поэтому я должен что-то упустить