Инициализировать агрегатный элемент в общем коде шаблона
Например,
template <typename T>
struct node {
T data;
node* pnext;
};
template <typename T, typename... Us>
void func(Us&&... args) {
// Initialize a node<T> with data initialized from args...
}
Пути, которые я могу придумать, и их ограничения.
node<T> v{ T(forward<Us>(args)...) }
, Это включает в себя инициализацию копирования, которая не работает, еслиT
не копируемый и неподвижный, например, атомарный тип.node<T> v{ {forward<Us>(args)...} }
, Это включает copy-list-initialization, которая не работает, если выбранный конструктор является явным. Например,node<unique_ptr<int>> n{ {new int()} }
не работает
Я предполагаю, что вопрос решен, если я могу как-то напрямую инициализировать (например, direct-list-initialization) агрегатный член. Тем не менее, я не понимаю, как это возможно, кроме написания пользовательского конструктора, что делает node
неагрегированный тип, который является излишним, и я не хочу этого делать. Любая идея?
1 ответ
C++14 не имеет эффективного решения этой дилеммы. Ну, пока еще не используется агрегатная инициализация. Если вы даете node<T>
конструктор переменных, тогда он может передать параметры непосредственно инициализатору элемента:
template <typename T>
struct node {
T data;
node* pnext;
template<typename ...Args>
node(Args ...&&args) : data(std::forward<Args>(args)...) {}
};
Таким образом, позволяя вам вызвать node<T> v( T(forward<Us>(args)...) )
, Конечно, это больше не совокупность.
Правила гарантированного отбора в C++17 позволяют node<T> v{ T(forward<Us>(args)...) }
не провоцировать копию или переместить.