【发布时间】:2021-07-08 10:12:10
【问题描述】:
我正在尝试使用以下代码遍历一个元组:
template <std::size_t I = 0, typename... Ts>
requires (I >= sizeof...(Ts))
static inline auto consume_all(std::tuple<Ts...>&&, auto) -> void {}
template <std::size_t I = 0, typename... Ts>
requires (I < sizeof...(Ts))
static inline auto consume_all(std::tuple<Ts...>&& tup, auto f) -> void {
f(std::get<I>(tup));
consume_all<I + 1, Ts...>(tup, f);
}
据我所知,上述定义没有任何问题。但是,当我尝试调用它时...:
template <typename F, typename T>
concept unary = requires(F&& f, T&& t) {
{
f(t)
} -> std::convertible_to<T>;
};
//...
//in struct definition:
const std::tuple<Fs...> funcs;
//...
//in method definition:
consume_all<Fs...>(
funcs,
[=, &t]<unary<T> F>(F f) {t = f(t);}
);
...我收到一个编译时错误,说两个模板都被忽略了:
No matching function for call to 'consume_all' in instantiation of member function 'chain<int, [function-typenames]>'
...
candidate template ignored: invalid explicitly-specified argument for template parameter 'I'
candidate template ignored: invalid explicitly-specified argument for template parameter 'I'
我看不出这个问题,因为... >= I 和... < I 的组合应该是包罗万象的。
编辑:
当指定 I (consume_all<0, Fs...>) 时,候选模板仍然会被忽略,尽管现在它们会产生更具描述性的错误:
No matching function for call to 'consume_all'
...
candidate template ignored: //issue
deduced type 'tuple<...>' of 1st parameter does not match adjusted type
'const tuple<...>' of argument
[with I = 0, Ts = <(lambda)>, f:auto = (lambda)]
candidate template ignored: //rightfully
constraints not satisfied
[with I = 0, Ts = <(lambda)>, auto:3 = (lambda)]
because '0U >= sizeof...(Ts)' (0 >= 1) evaluated to false
【问题讨论】:
-
顺便说一句,在 C++17 中:
std::apply([&](auto&&... args){ (f(args), ...); }, tup);. -
std::tuple<Ts...>&&不是转发引用,所以你需要consume_all(std::move(funcs), lambda)
标签: c++ templates tuples iteration c++-concepts