Некоторое время назад попробовал разобраться с тем, как работает трюк, описанный в статье "Reflection in C++14". И очень долго тупил и не понимал, как же так получается, что попытки увеличивать количество параметров в выражении aggregate initialization ведут к должному результату... Т.е. сперва делается T{a1}, затем T{a1, a2}, затем T{a1, a2, a3} и т.д. И останавливается это все на aN, где N и есть количество полей в структуре T.
А тупил и не понимал потому, что считал, что в выражении aggregate initialization нужно передавать начальные значения для всех полей структуры T. Т.е., если в T четыре поля, то и в aggregate initialization нужно отдать именно четыре значения. Не больше, не меньше. А именно четыре.
Ну и вот оказалось, что в главном-то я и не прав. В aggregate initialization можно отдать и меньше значений. Вот для иллюстрации работающий пример (убедиться можно на wandbox):
#include <iostream> struct Demo { int a_; int b_; int c_; int d_; }; std::ostream & operator<<(std::ostream & to, const Demo & d) { return (to << '(' << d.a_ << ',' << d.b_ << ',' << d.c_ << ',' << d.d_ << ')'); } int main() { { Demo d{}; std::cout << "First: " << d << std::endl; } { Demo d{1, 0}; std::cout << "Second: " << d << std::endl; } { Demo d{1, 0, 42, 15}; std::cout << "Third: " << d << std::endl; } } |
Вот уж, что называется, век живи, век учись, а помрешь все равно дураком ;)
2 комментария:
Это ещё с C пошло.
@sergegers
Я помню, что в Сях можно было делать что-то вроде char s[10] = {0, 1, 2};
Но вот по поводу C++, когда aggregate initialization разрешили применять к классам/структурам, у меня почему-то осталось убеждение, что количество инициализирующих значений должно совпадать с количеством полей в классе/структуре. А вот почему это убеждение сложилось уже и не вспомнить.
Отправить комментарий