Для Kotlin вы можете использовать context
непосредственно в фрагментах. Но в некоторых случаях вы найдете ошибку, например
Тип несоответствия: inferred type is Context? но ожидался контекст
blockquote>, для которого вы можете это сделать
val ctx = context ?: return textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))
Интересно, что об этом говорит стандарт C ++? Является ли законным и гарантированным всегда работать?
blockquote>Да. Это совершенно законно. Полностью стандартное соответствие.
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-инициализатор.
blockquote>[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 для ссылки на инициализированный объект. ]
blockquote>Как вы можете видеть, в приведенном выше примере есть и другая интересная вещь, и комментарий к самому стандарту.
BTW, как сторона примечания, почему вы не принимаете параметр в качестве ссылки const :
Blah(const std::vector<int> & vec): vec(vec) {} ^^^^const ^reference
Он избегает ненужной копии исходного векторного объекта.
Гарантируется всегда работать (я использую его довольно часто). Компилятор знает, что список инициализаторов имеет форму: member(value)
, и поэтому он знает, что первый vec
в vec(vec)
должен быть членом. Теперь в аргументе инициализации члена могут использоваться оба члена, аргументы конструктору и другим символам, как и в любом выражении, которое будет присутствовать внутри конструктора. На этом этапе он применяет регулярные правила поиска, а аргумент vec
скрывает член vec
.
В разделе 12.6.2 стандарта рассматриваются инициализация, и в нем объясняется процесс с параграфом 2, касающийся поиск члена и параграфа 7 с поиском аргумента.
Имена в списке выражений mem-инициализатора оцениваются в объеме конструктора, для которого mem-initializer указано. [Пример:
blockquote>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) {} };
Как уже ответили другие: Да, это законно. И да, это гарантировано стандартом для работы.
И я считаю это ужасным каждый раз, когда вижу это, заставляя меня делать паузу: «vec(vec)
? WTF? Ах да, vec
- это член переменной ... "
Это одна из причин, почему многие, включая меня, любят использовать соглашение об именах, которое дает понять, что переменная-член является переменной-членом. Соглашения, которые я видел, включают добавление суффикса подчёркивания (vec_
) или префикса m_
(m_vec
). Затем инициализатор читает: vec_(vec)
/ m_vec(vec)
, что не вызывает затруднений.
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