C++:迭代元组时忽略候选模板
C++: candidate template ignored when iterating over tuple
我正在尝试使用以下代码遍历元组:
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);
}
据我所见,上面的定义并没有错。但是,当我尝试调用它时...:[=18=]
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
你打电话给
consume_all<Fs...>
你不见了I
。你需要
consume_all<0, Fs...>
在查看@Jarod42 的评论后,我找到了一种更好的方法来遍历元组,从而避开模板问题。
将 consume_all
定义为迭代函数不是正确的方法。
相反,consume_all
应该使用 std::apply(func, tup)
定义,它解析元组 tup
作为 func
.
的参数
这现在将迭代元组的问题转换为迭代参数包的问题(这更容易)。
遍历参数包的元素:
template <typename F>
[[maybe_unused]] static inline void consume(F) {}
//^^^ Empty Base Case ^^^
template <typename F, typename Arg>
requires std::invocable<F, Arg>
[[maybe_unused]] static inline void consume(F f, Arg arg) {
f(arg);
}
//^^^ Single Arg Base Case ^^^
template <typename F, typename Arg, typename... Args>
requires std::invocable<F, Arg>
static inline void consume(F f, Arg arg, Args... args) {
f(arg);
consume<F, Args...>(f, args...);
}
//^^^ Recursive General Case ^^^
现在我们已经定义了一个函数来使用参数包的每个元素,我们现在可以正确定义 consume_all
重新定义consume_all:
template <typename F, typename... Args>
[[maybe_unused]] static inline void consume_all(F f, std::tuple<Args...> tup) {
std::apply(
[&f](auto&&... args){
consume(f, args...);
},
tup
);
}
原题求解:
consume_all(
[&t]<unary<T> F>(F f) {t = f(t);},
funcs
);
我希望这对遇到类似问题的其他人有所帮助
我正在尝试使用以下代码遍历元组:
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);
}
据我所见,上面的定义并没有错。但是,当我尝试调用它时...:[=18=]
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
你打电话给
consume_all<Fs...>
你不见了I
。你需要
consume_all<0, Fs...>
在查看@Jarod42 的评论后,我找到了一种更好的方法来遍历元组,从而避开模板问题。
将 consume_all
定义为迭代函数不是正确的方法。
相反,consume_all
应该使用 std::apply(func, tup)
定义,它解析元组 tup
作为 func
.
这现在将迭代元组的问题转换为迭代参数包的问题(这更容易)。
遍历参数包的元素:
template <typename F>
[[maybe_unused]] static inline void consume(F) {}
//^^^ Empty Base Case ^^^
template <typename F, typename Arg>
requires std::invocable<F, Arg>
[[maybe_unused]] static inline void consume(F f, Arg arg) {
f(arg);
}
//^^^ Single Arg Base Case ^^^
template <typename F, typename Arg, typename... Args>
requires std::invocable<F, Arg>
static inline void consume(F f, Arg arg, Args... args) {
f(arg);
consume<F, Args...>(f, args...);
}
//^^^ Recursive General Case ^^^
现在我们已经定义了一个函数来使用参数包的每个元素,我们现在可以正确定义 consume_all
重新定义consume_all:
template <typename F, typename... Args>
[[maybe_unused]] static inline void consume_all(F f, std::tuple<Args...> tup) {
std::apply(
[&f](auto&&... args){
consume(f, args...);
},
tup
);
}
原题求解:
consume_all(
[&t]<unary<T> F>(F f) {t = f(t);},
funcs
);
我希望这对遇到类似问题的其他人有所帮助