gpt4 book ai didi

c++ - 当 i 不是常量表达式时寻址 std::tuple 的第 i 个成员?

转载 作者:行者123 更新时间:2023-12-02 01:09:39 26 4
gpt4 key购买 nike

假设我有以下函数模板:

template<typename T>
void mutate(T& t) { /*...*/ }

我有以下类模板:

template<typename... Args>
class Processor {
std::tuple<Args...> tup;

// call mutate on the ith tuple element
void process(size_t i) {
mutate(std::get<i>(tup)); // ERROR
}
}

这不起作用,因为 processi 参数不是常量表达式。 (它不能是常量表达式,因为 i 直到运行时才知道)

在不修改processmutuate的签名的情况下,是否有某种方法可以有效地完成这项工作?即如何更改 process 的实现,以便它在 tup 的第 i 成员上调用 mutate

最佳答案

您需要获取运行时索引并将其提升为常量表达式。最简单的方法就是使用 Boost.Mp11它附带了一个专门用于此目的的函数:

template<typename... Args>
class Processor {
std::tuple<Args...> tup;

// call mutate on the ith tuple element
void process(size_t i) {
mp_with_index<sizeof...(Args)>(i, [&](auto I){
mutate(std::get<I>(tup));
});
}
}

mp_with_index 的作用是采用常量表达式表示最大大小 (sizeof...(Args)) 和运行时大小 (i) code>),然后使用一个整型常量调用您的可调用对象(lambda),该常量是将运行时大小提升为常量表达式。

<小时/>

这可以使用 std::index_sequence 自行实现,方法是构建函数指针数组,然后调用正确的指针:

template <size_t... Is, typename F>
decltype(auto) mp_with_index(size_t i, F f, std::index_sequence<Is...>) {
using R = decltype(f(std::integral_constant<size_t, 0>{}));
using P = R(*)(F&);
static constexpr P fns[] = {
+[](F& f) -> R { return f(std::integral_constant<size_t, Is>{}); }...
};
return fns[i](f);
}

template <size_t N, typename F>
decltype(auto) mp_with_index(size_t i, F f) {
return mp_with_index(i, f, std::make_index_sequence<N>());
}

(请注意,Boost.Mp11 实现比这更好,这只是功能上正确的)。

关于c++ - 当 i 不是常量表达式时寻址 std::tuple 的第 i 个成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58585380/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com