При желании поддержка конструкции initializer_list для шаблонов, может быть, упаковка контейнеров

Если у меня есть шаблон, который оборачивает стандартный контейнер, кажется, я могу достаточно легко делегировать конструктор initializer_list:

template<typename T>
struct holder {
T t_;

holder() :
t_() {}

holder(std::initializer_list<typename T::value_type> values)
: t_(values) {}

};

Так что это прекрасно работает с std :: vector, например.

int main(int argc, char* argv[]) {

holder<std::vector<int>> y{1,2,3};
return EXIT_SUCCESS;
}

Но это, очевидно, не работает для T как ‘int’ или любого другого типа, который не имеет вложенной value_type typedef. Итак, я хотел бы использовать какой-нибудь метод enable_if или аналогичный трюк, чтобы не вызывать конструктор initializer_list, если только T не определяет вложенный value_type typedef и не может быть создан из std :: initializer_list.

Я попробовал следующее, но это все еще не работает, потому что компилятор (clang ++ 3.1 в моем случае) все еще отключается по недопустимому T :: value_type, когда T является int:

holder(typename std::enable_if<std::is_constructible<T, std::initializer_list<typename T::value_type>>::value, std::initializer_list<typename T::value_type>>::type values)
: t_(values) {}

Любые мысли о том, как выразить концепцию «передайте этот шаблон в T конструктору списка инициализаторов поверх value_type T, если и только если T имеет typedef value_type и может быть создан из initializer_list из T :: value_type».

10

Решение

SFINAE работает только при замене параметров шаблона (следовательно, S в SFINAE). Следующие работы:

template<typename T>
struct holder {
T t_;

holder() :
t_() {}

template<typename U = T>
holder(typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value,
std::initializer_list<typename U::value_type>>::type values)
: t_(values) {}

};

Если вы не используете шаблонную функцию, то весь тип будет создан для типа int(в вашем примере), что приводит к ошибке компилятора.

Обратите внимание, что вы могли бы сделать подпись функции более приятной, если бы использовали дополнительный параметр шаблона:

template<typename U = T, class = typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value, bool>::type>
holder(std::initializer_list<typename U::value_type> values)
: t_(values) {}
5

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

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

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