У меня есть функция, применяющая данную функцию f
к заданному std::tuple
t
, как показано ниже, в которой, если t
имеет неправильный размер, генерируется сообщение об ошибке времени компиляции. Мне было интересно, можно ли написать это по-другому, чтобы при неправильном размере кортежа вызов функции не происходил (возможно, с использованием enable_if
или что-то в этом роде) и генерировалось сообщение об ошибке времени выполнения (вместо ошибки времени компиляции сообщение).
Заранее спасибо.
#include <tuple>
#include <iostream>
#include <functional>
template<int ...> struct seq {};
template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {};
template<int ...S> struct gens<0, S...>{ typedef seq<S...> type; };
template <typename R, typename Tp, typename ...FArgs>
struct t_app_aux {
template<int ...S>
R static callFunc(std::function<R (FArgs...)> f,Tp t,seq<S...>) {
return f(std::get<S>(t) ...);
}
};
template <typename R, typename Tp, typename ...FArgs>
R t_app(std::function<R (FArgs...)> f, Tp t) {
static_assert(std::tuple_size<Tp>::value == sizeof...(FArgs), "type error: t_app wrong arity"); //wrong size generates a compile error, how about runtime check?
return t_app_aux<R, Tp, FArgs...>::callFunc(f,t,typename gens<sizeof...(FArgs)>::type());
}
int main(void)
{
std::tuple<int, float, double> t = std::make_tuple(1, 1.2, 5);
std::function<double (int,float,double)> foo = [](int x, float y, double z) {
return x + y + z;
};
std::cout << t_app(foo,t) << std::endl;
}
-- Обновлять --
Немного мотивации и объяснения того, что я имею в виду. Это может быть политически некорректно, но скажем, я хочу сравнить входной кортеж с фиксированным кортежем, определенным внутри функции шаблона compare_me
(скажем, внутренний кортеж make_tuple(2,3)
). Если бы я мог подавить ошибку времени компиляции, то я мог бы вернуть false
на compare_me(make_tuple(1,2,3))
или compare_me(make_tuple(1,2))
и true
только на make_tuple(2,3)
. На практике тот же метод можно использовать для написания шаблона eq
для сравнения двух кортежей потенциально разных размеров и возврата false
, если их размеры не совпадают.
Несоответствие размера можно рассматривать как ошибку компиляции. И я согласен с тем, что настоящий провал должен быть обнаружен как можно раньше. Но я предполагаю, что бывают моменты, когда можно проявить снисходительность или пересмотреть то, что является настоящим провалом. Это верно, особенно если учесть, что существуют такие функции, как std::tuple_cat
, которые фактически могут дать вашей функции кортеж различных размеров.
template<typename Tp> int f(Tp t) { return tuple_size<Tp>::value;}
уже может обрабатывать кортежи разных размеров. Я спрашиваю, можно ли, например, сравнить два кортежа разных размеров без возникновения ошибки компиляции. - person tinlyx   schedule 23.01.2014if (true) f(make_tuple()); else f(make_tuple(1,2));
. Я думаю, что до тех пор, пока не используется возвращаемый тип или повторное использование переменных, кортежи разных размеров можно использовать вместе. - person tinlyx   schedule 23.01.2014