Структурная привязка и тип переменных - PullRequest
1 голос
/ 24 марта 2020

Я хотел бы задать вопрос о структурном связывании и о том, как переменные получают свои типы. Вот код, который я компилирую.

struct T {
  explicit T(int a = 1) {
    a_ = a;
    std::cout << "Default" << std::endl;
  }
  T(const T& t) {
    a_ = t.a_;
    std::cout << "Copy" << std::endl;
  }
  int a_;
};

int main() {

  std::tuple<bool, T> bi{true, T(1)};
  std::cout << "START" << std::endl;
  auto& [b, i] = bi;
  static_assert(std::is_same<decltype(i), T>::value);
  std::cout << i.a_ << std::endl;
  i.a_++;
  std::cout << i.a_ << std::endl;
  std::cout << (&i == &get<1>(bi)) << std::endl;


  return 0;
}

Код компилируется, и в результате получается:

Default
Copy
START
1
2
1

Как видите, переменная i фактически ссылается на get<1>(bi). Однако тип переменной i равен T, поскольку std::is_same<decltype(i), T>::value. Не могли бы вы объяснить, почему структурное связывание работает таким образом? Я читал об этом в книге «Шаблоны C ++: Полное руководство», и авторы утверждают, что переменная i должна иметь тип std::tuple_element<1, std::tuple<bool, T> >::type&&. Я не понимаю, почему decltype(i) это просто T.

1 Ответ

3 голосов
/ 24 марта 2020

decltype это смешно. Его спецификация содержит специальное предложение для структурированных привязок

4 Для выражения e тип, обозначаемый decltype(e), определяется следующим образом:

  • , если e - это не заключенное в скобки id-выражение, именующее структурированную привязку ([dcl.struct.bind]), decltype(e) - ссылочный тип, как указано в спецификации объявления структурированной привязки;

  • ...

Поэтому, хотя каждое структурированное связывание действительно является ссылкой в ​​кортеж, decltype сообщает тип референта , Вероятно, поскольку структурированные привязки должны восприниматься как обычные именованные переменные.

...