我有一个元组
Args
由函数签名生成。
我想迭代元组,检查参数是否是特定类型,如果不是,则返回一个字符串。
所以我想出了以下代码:
std::tuple<Args...> arguments;
Object* runtime_arguments = new Object[N];
fill_args(runtime_arguments, N);
auto is_valid_arguments = std::apply([&runtime_arguments](auto... arguments) {
std::size_t i = 0;
for (auto arg : {arguments...})
{
std::string error;
if (!is_valid_type<decltype(arg)>(runtime_arguments[i++], error))
{
return false;
}
}
return true;
}, arguments);
template<typename T>
bool is_valid_type(Object* object, std::string& error)
{
if constexpr(std::is_same<T, std::int32_t>::value)
{
return object->is_type('I');
}
else
{
static_assert(!is_native_type<T>::value, "Invalid Type");
}
return false;
}
我可以在编译时进行,但它会返回布尔值和错误字符串的元组,我不希望这样。我希望它打破循环,并在出现如上所示的问题时立即返回。
如果
std::initializer_list<auto>{arguments...}
是同构的,因此如果元组是:
std::tuple<Element*, char, bool>
它当然不会编译。
有没有办法在元组中的元素上循环,并在第一个问题上中断?
也许是这样的:
for_each(tuple, [](auto& e) {
return true;
return false;
});
所以我想到了这样的事情:
template<size_t I = 0, typename Fn, typename... Tp>
void for_each(std::tuple<Tp...>&& t, Fn &&fn)
{
if (!fn(std::get<I>(t)) {
return false;
}
if constexpr(I+1 != sizeof...(Tp)) {
return for_each<I+1>(std::forward<std::tuple<Tp...>>(t), std::forward<Fn>(fn));
}
}
有没有更好的方法来做到这一点或类似的事情(最好不要递归)?