C++ Предоставить конструктор списка инициализаторов для шаблона класса
У меня есть шаблон класса Templ с параметром шаблона T, а класс Templ имеет член данных типа T, называемый obj. Я написал шаблон конструктора переменной, который пересылает аргументы в конструктор obj:
template <class T>
class Templ
{
public:
template <class... Args> explicit Templ (Args&&... args)
: obj (std::forward<Args>(args)...)
{
}
private:
T obj;
};
Теперь я понял, что тип T может быть классом с конструктором списка инициализации, и я хочу, чтобы он был доступен через Templ. Итак, я проверил, что std::list::emplace
а также std::make_shared
делать. Они имеют переменную функцию, как у меня, но у них нет переопределений, принимающих список инициализации. По какой-то причине.
Итак, первый вопрос: почему? Я имею в виду, что если я использую некоторый класс T с ctor списка инициализации, а затем я использую std::list<T>
? Почему list::emplace не имеет версии, которая принимает initializer_list? Может быть, есть веская причина, по которой я должен это сделать... так что я хочу знать.
Кроме того, независимо от того, что делает STL - я должен предоставить ctor init-list как хороший дизайн? Я имею в виду, это так же, как вариационный ctor, верно? Позволяет пользователю выбрать любой тип или класс T для использования с Templ<> и напрямую вызывать любой ctor, определенный для T. Даже если это ctor, принимающий список инициализации.
1 ответ
Проблема с пересылкой initializer_list
конструкторы в том, что все типы аргументов, кроме самых тривиальных, не выводимы ( шаблоны не всегда предполагают типы списков инициализаторов):
#include <map>
template<typename T> struct U {
T t;
template<typename...A> explicit U(A&&...a): t(std::forward<A>(a)...) {}
template<typename L, typename = typename std::enable_if<
std::is_constructible<T, std::initializer_list<L>>::value>::type>
explicit U(std::initializer_list<L> l): t(l) {}
};
U<std::map<int, int>> m{{{0, 1}, {2, 3}}}; // fails, couldn't deduce 'L'
Так как вам придется написать m{std::initializer_list<...>{...}}
в большинстве случаев нет особого смысла предоставлять его только для примитивов, и уж точно не для стандарта.
Если вы думаете что нибудь интересное initializer_list
Скорее всего, аргументы относятся к типам контейнеров, вы можете посмотреть на подход, принятый в разделе " Опционально", поддерживающем конструкцию initializer_list для шаблонов, возможно, упаковывающих контейнеры.