if-with-initializer в примере объявления структурированной привязки плохо сформирован? - PullRequest
0 голосов
/ 15 декабря 2018

Я читал декларацию структурированной привязки на 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 будет чем?!?Наоборот, это нарушит часть выражения.Но он явно компилируется и запускается, поэтому я должен что-то упустить

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Я чувствую, что вы запутались из-за структурированной привязки и если с инициализатором, но простой способ взглянуть на это - разложить их.

if (auto [a, b] = foo(); b)

Состоит из двух частей = первая инициализатор (auto [a, b] = foo()) и второй (б) является условием.Это в точности эквивалентно

{
auto [a, b] = foo(); 
if (b)
}

. В приведенном выше примере a и b будут выводиться для любого типа возврата foo мандатов, не имея ничего общего с условием if ниже этого,

0 голосов
/ 15 декабря 2018

, который говорит, что объявление плохо сформировано, если выражение находится в списке идентификаторов

Это не говорит об этом.В нем говорится, что если выражение использует какое-либо из имен в идентификаторе-списке , оно неверно сформировано.myset.insert("Hello") не делает этого, так что все в порядке.

std::set::insert возвращает std::pair<std::set::iterator, bool>, где std::set::iterator обозначает положение элементов, а bool указывает, был ли он вставлен или нет.Таким образом, auto [iter, success] = myset.insert("Hello") захватывает эту пару и устанавливает iter на std::set::iterator и success на bool.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...