c ++ 11 — 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 делать. У них есть функция variadic, как у меня, но у них нет переопределений, принимающих список инициализации. По какой-то причине.

Итак, первый вопрос: почему? Я имею в виду, что если я использую некоторый класс T с ctor списка инициализации, а затем я использую std::list<T>? Почему list :: emplace не имеет версии, которая принимает initializer_list? Может быть, есть веская причина, по которой я должен это сделать … так что я хочу знать.

Кроме того, независимо от того, что делает STL — я должен предоставить ctor init-list как хороший дизайн? Я имею в виду, это так же, как вариационный ctor, верно? Разрешение пользователю выбирать любой тип или класс T для использования с Templ<> и напрямую вызывать любой ctor, определенный для T. Даже если это ctor, принимающий список инициализации.

5

Решение

Проблема с пересылкой 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 для шаблонов, может быть, упаковка контейнеров.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]