этот оператор и назначение конструктора [дубликат]

Для Kotlin вы можете использовать context непосредственно в фрагментах. Но в некоторых случаях вы найдете ошибку, например

Тип несоответствия: inferred type is Context? но ожидался контекст

, для которого вы можете это сделать

val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))
50
задан Lightness Races in Orbit 31 May 2011 в 10:14
поделиться

3 ответа

Интересно, что об этом говорит стандарт C ++? Является ли законным и гарантированным всегда работать?

Да. Это совершенно законно. Полностью стандартное соответствие.

Blah(std::vector<int> vec): vec(vec){}
                             ^   ^                           
                             |   |
                             |    this is the argument to the constructor
                             this is your member data

Поскольку вы попросили ссылку в стандарте, вот пример.

§12.6.2 / 7

< blockquote>

Имена в списке выражений mem-инициализатора оцениваются в области конструктора, для которого указан mem-инициализатор.

[Example:
class X {
 int a;
 int b;
 int i;
 int j;
 public:
 const int& r;
  X(int i): r(a), b(i), i(i), j(this->i) {}
                      //^^^^ note this (added by Nawaz)
};

инициализирует X :: r для ссылки на X :: a, инициализирует X :: b со значением параметра конструктора i, инициализирует X :: i с значение параметра конструктора i и инициализирует X :: j значением X :: i; это происходит каждый раз, когда создается объект класса X. ]

[Примечание: поскольку mem-инициализатор оценивается в области конструктора, этот указатель может использоваться в списке выражений mem-initializer для ссылки на инициализированный объект. ]

Как вы можете видеть, в приведенном выше примере есть и другая интересная вещь, и комментарий к самому стандарту.


BTW, как сторона примечания, почему вы не принимаете параметр в качестве ссылки const :

 Blah(const std::vector<int> & vec): vec(vec) {}
      ^^^^const              ^reference

Он избегает ненужной копии исходного векторного объекта.

66
ответ дан Nawaz 20 August 2018 в 07:32
поделиться
  • 1
    Thx для быстрого ответа, однако в стандартном документе (n3290) я не могу найти списки инициализации, в какой главе? – Nils 31 May 2011 в 09:50
  • 2
    Итак, если я принимаю его как ссылку, он просто копируется один раз? От области действия до переменной-члена. Но если я не принимаю параметр в качестве ссылки, он снова копируется только в области конструктора, верно? Thx для указания этого. – Nils 31 May 2011 в 09:56
  • 3
    В C ++ 0x лучше принять его по значению, а затем переместить его в пункт назначения: Blah(std::vector<int> vec) : vec(std::move(vec)){}. Вы можете имитировать это в C ++ 03 следующим образом: Blah(std::vector<int> vecSrc) { std::swap(vec, vecSrc); }. – GManNickG 31 May 2011 в 10:04
  • 4
    @Tomalak: lol, я все еще удивляюсь, что вы находите это нечитаемым. Это довольно прямолинейно, и я подумал, что это обычное дело. – GManNickG 31 May 2011 в 17:16
  • 5
    @GMan: Я все еще рассматриваю его как «трюк». Я знаю, что он делает, но это не очевидно из кода с первого взгляда, что это означает означает , я думаю. Вы должны продумать шаги, чтобы понять, что исходный оригинальный объект нигде не перемещается. – Lightness Races in Orbit 31 May 2011 в 17:22
  • 6

Гарантируется всегда работать (я использую его довольно часто). Компилятор знает, что список инициализаторов имеет форму: member(value), и поэтому он знает, что первый vec в vec(vec) должен быть членом. Теперь в аргументе инициализации члена могут использоваться оба члена, аргументы конструктору и другим символам, как и в любом выражении, которое будет присутствовать внутри конструктора. На этом этапе он применяет регулярные правила поиска, а аргумент vec скрывает член vec.

В разделе 12.6.2 стандарта рассматриваются инициализация, и в нем объясняется процесс с параграфом 2, касающийся поиск члена и параграфа 7 с поиском аргумента.

Имена в списке выражений mem-инициализатора оцениваются в объеме конструктора, для которого mem-initializer указано. [Пример:

class X {
   int a;
   int b;
   int i;
   int j;
public:
   const int& r;
   X(int i): r(a), b(i), i(i), j(this->i) {}
};
9
ответ дан David Rodríguez - dribeas 20 August 2018 в 07:32
поделиться

Как уже ответили другие: Да, это законно. И да, это гарантировано стандартом для работы.

И я считаю это ужасным каждый раз, когда вижу это, заставляя меня делать паузу: «vec(vec)? WTF? Ах да, vec - это член переменной ... "

Это одна из причин, почему многие, включая меня, любят использовать соглашение об именах, которое дает понять, что переменная-член является переменной-членом. Соглашения, которые я видел, включают добавление суффикса подчёркивания (vec_) или префикса m_ (m_vec). Затем инициализатор читает: vec_(vec) / m_vec(vec), что не вызывает затруднений.

0
ответ дан user1387866 20 August 2018 в 07:32
поделиться
Другие вопросы по тегам:

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