Эквивалент layout_column
и layout_row
, как и для всех параметров layout_...
, можно найти как параметр подкласса LayoutParams
.
В этом случае это GridLayout.LayoutParams
, и мы используем его так (для сетки 2x2 с подвью в последней строке и столбце, центрированной внутри ячейки):
gridLayout.setColumnCount(2);
gridLayout.setRowCount(2);
gridLayout.addView(subview, new GridLayout.LayoutParams(
GridLayout.spec(1, GridLayout.CENTER),
GridLayout.spec(1, GridLayout.CENTER)));
Руководство по выведению шаблонов - это шаблоны, связанные с классом шаблона, которые сообщают компилятору, как перевести набор параметров (и их типы) в аргументы шаблона.
Самый простой пример - это std::vector
и его конструктор, который принимает пару итератора.
template<typename Iterator>
void func(Iterator first, Iterator last)
{
vector v(first, last);
}
Компилятор должен выяснить, какой тип vector<T>
T
будет. Мы знаем, что такое ответ; T
должен быть typename std::iterator_traits<Iterator>::value_type
. Но как мы можем сообщить компилятору без , чтобы набрать vector<typename std::iterator_traits<Iterator>::value_type>
?
. Вы используете руководство по выводу:
template<typename Iterator> vector(Iterator b, Iterator e) ->
vector<typename std::iterator_traits<Iterator>::value_type>;
Это говорит компилятору, что , когда вы вызываете конструктор vector
, соответствующий этому шаблону, он выдает специализацию vector
, используя код справа от ->
.
Вам нужны справочники, когда вычитание типа из аргументы не основаны на типе одного из этих аргументов. Инициализация vector
из initializer_list
явно использует vector
's T
, поэтому ему не нужно руководство.
Левая сторона необязательно указывает конструктор. Способ его работы состоит в том, что если вы используете вычет конструктора шаблона для типа, он соответствует аргументам, которые вы передаете во всех руководствах по вычитанию (фактические конструкторы первичного шаблона предоставляют неявные руководства). Если есть совпадение, он использует это, чтобы определить, какие аргументы шаблона должны указывать на тип.
Но как только этот вывод будет выполнен, как только компилятор определит параметры шаблона для типа, инициализация объекта этого типа происходит так, как будто ничего из этого не произошло. То есть выбранное руководство вычитания не должно соответствовать выбранному конструктору .
Это также означает, что вы можете использовать направляющие с агрегатами и агрегатной инициализацией:
template<typename T>
struct Thingy
{
T t;
};
Thingy(const char *) -> Thingy<std::string>;
Thingy thing{"A String"}; //thing.t is a `std::string`.
. Руководство по вычитанию используется только для определения инициализированного типа. Фактический процесс инициализации работает точно так же, как и раньше, после того, как это было сделано.
Вот пример использования руководства по дедукции, который я использовал для упрощения построения прокси-объекта в прокси-шаблоне. Надеюсь, что это может дать вам некоторые идеи Простейшие вещи, которые мы можем сделать прокси-шаблон, используя современный c ++ . Руководствами дедукции, которые я использовал, являются:
ProxyContainer(vector<string>&) -> ProxyContainer<<vector<string>, string>;
ProxyContainer(int*) -> ProxyContainer<<vector<int>, int>;
vector v{first, last};
не пойдет правильно :( – T.C. 3 December 2016 в 21:02std::string{32,'*'}[0] == ' '
(для ASCII). Но все это было верно, так как C ++ 11. – Arne Vogel 20 October 2017 в 14:16