Предположим, что я написал общие функции отображения для кортежей STL (кортеж, пара), а также последовательности STL (вектор, список, deque). Теперь я хочу написать глобальную функцию карты, вызывающую соответствующие специальные функции с учетом типов ввода.Специализируется на пакете параметров шаблона по умолчанию
У меня есть кое-что вдоль линий
template <typename... Ts>
struct mappable {
static constexpr bool is_instance = false;
};
template <typename... Tuples, typename = require<all<is_stl_tuple, Tuples...>::value>>
struct mappable<Tuples...> {
template <typename Func>
auto map(Func&& f, Tuples&&... ts) {
return tuple::map(std::forward<Func>(f), ts...);
}
static constexpr bool is_instance = true;
};
template <typename... Sequences, typename = require<all<is_stl_sequence, Sequences...>::value>>
struct mappable<Sequences...> {
template <typename Func>
auto map(Func&& f, Sequences&&... seqs) {
return sequence::map(std::forward<Func>(f), seqs...);
}
static constexpr bool is_instance = true;
};
template <typename Func, typename... Ts>
auto map(Func&& f, Ts&&... ts) {
static_assert(mappable<Ts...>::is_instance, "Tried calling map on unsupported types. Mappable arguments must be supplied.");
return mappable<Ts...>::map(std::forward<Func>(f), std::forward<Ts>(ts)...);
}
Хотя мы надеемся, самообъясняющими тип проверки функции DEFS:
// true iff Unary<Ts>::value... == true for at least one Ts
template <template <typename> class Unary, typename... Ts>
struct any;
// true iff Unary<Ts>::value... == true for all Ts
template <template <typename> class Unary, typename... Ts>
struct all;
template <bool B>
using require = typename std::enable_if<B>::type;
Очевидно, что это не будет (и не) работать, так как я специализируются на аргументах по умолчанию. Есть ли способ сделать это, а если нет (и мне нужно перепроектировать), как бы вы решили перепроектировать эти функции? Последовательность :: Карта должна, например, взять любую комбинацию СТЛ последовательностей, так что все идеи у меня есть о реструктуризации просто перекладывать проблему в другом месте ...
Заранее спасибо за любую помощь ...
Edit: As просьба здесь примеры использования (на самом деле мой тестовый код для него) перед тем я начал делать выше:
auto t0 = std::make_tuple(2.f, -5, 1);
auto t1 = std::make_tuple(1, 2);
auto b0 = tuple::map([] (auto v) { return v > decltype(v)(0); }, t0);
auto r0 = tuple::map([] (auto v0, auto v1) { return v0 + v1; }, t0, t1);
// b0 is tuple<bool, bool, bool>(true, false, true)
// b1 is tuple<float, int>(3.f, -3)
и для последовательностей:
std::vector<float> s0 = {1.f, 2.f, 3.f, 0.f};
std::list<int> s1 = {3, 0, -2};
auto r = sq::map([] (auto v0, auto v1) { return v0 + v1; }, s0, s1);
// type of r is compound type of first argument (vector here), result is
// vector<float>(4.f, 2.f, 1.f)
Реализации этих функций карты совершенно разные - цель моего подхода выше - уметь отбрасывать пространство имен и просто использовать карту, чтобы она делала «Правильную вещь».
Кстати, вы злоупотребляя 'forward'. Это только для * выведенных * типов. –
И можете ли вы привести пример использования? –
@KerrekSB: 1. Вы имеете в виду std :: forward ... и std :: forward ... Надеюсь, и я буду прав. 2. Отредактировал вопрос, чтобы дать некоторые примеры ... –