gpt4 book ai didi

c++ - 如何通过标准元组操作正确转发和使用 constexpr 结构的嵌套元组

转载 作者:行者123 更新时间:2023-12-05 01:04:16 25 4
gpt4 key购买 nike

我想通过 structconstexpr constructor 存储传递的数据,并将数据存储在 std::tuple ,执行各种TMP/compile time操作。

实现

template <typename... _Ts>
struct myInitializer {
std::tuple<_Ts...> init_data;

constexpr myInitializer(_Ts&&... _Vs)
: init_data{ std::tuple(std::forward<_Ts>(_Vs)...) }
{}
};

存储数据使用轻量级强类型结构,通过左值和右值辅助重载生成:

template <typename T, typename... Ts>
struct data_of_t {
using type = T;
using data_t = std::tuple<Ts...>;
data_t data;

constexpr data_of_t(Ts&&... _vs)
: data(std::forward<Ts>(_vs)...)
{}
};
template<typename T, typename... Ts>
constexpr auto data_of(Ts&&... _vs) {
return data_of_t<T, Ts...>(std::forward<Ts>(_vs)...);
};

template<typename T, typename... Ts>
constexpr auto data_of(Ts&... _vs) {
return data_of_t<T, Ts...>(std::forward<Ts>(_vs)...);
};

它是这样实现的

template <typename T = int>
class test {
public:
static constexpr auto func(int p0=0, int p1=1, int p2=3) noexcept {
return data_of <test<T>>
(data_of<test<T>>(p0, p1));
}
};
int main() {
constexpr // fails to run constexpr // works without
auto init = myInitializer (
test<int>::func()
,test<int>::func(3)
,test<int>::func(4,5)
);

std::apply([&](auto&&... args) {
//std::cout << __PRETTY_FUNCTION__ << std::endl;
auto merged_tuple = std::tuple_cat(std::forward<decltype(args.data)>(args.data)...);
}
, init.init_data);
}

切入正题

如果 myInitializer 实例是 constexpr,则

std::tuple_cat 失败。

std::apply([&](auto&&... args) {
auto merged_tuple = std::tuple_cat(std::forward<decltype(args.data)>(args.data)...);

它似乎与通过 constexpr 添加的 const 限定符有关。

如何解决这个问题?

https://godbolt.org/z/j5xdT39aE 上查看完整示例

最佳答案

这个:

auto merged_tuple = std::tuple_cat(std::forward<decltype(args.data)>(args.data)...);

不是转发数据的正确方式。 decltype(args.data)将为您提供该数据成员的类型 - 它不是 args 的常量或值类别的函数.让我们举一个更简单的例子:

void f(auto&& arg) {
g(std::forward<decltype(arg.data)>(arg.data));
}

struct C { int data; };

C c1{1};
const C c2{2};

f(c1);
f(c2);
f(C{3});

所以我在这里打了三个电话到 f (分别调用 f<C&>f<const C&>f<C> )。在所有三种情况下,decltype(arg.data)是...只是int .这就是 C::data 的类型是。但这不是它需要被转发的方式(它不会为 c2 编译,因为我们正试图抛弃 const-ness——就像你的例子一样——它会错误地搬出c1)。

你要的是转发arg ,分别,然后然后访问数据:

void f(auto&& arg) {
g(std::forward<decltype(arg)>(arg).data);
}

现在,decltype(arg)实际上从实例化到实例化是不同的,这很好地表明我们正在做一些明智的事情。

关于c++ - 如何通过标准元组操作正确转发和使用 constexpr 结构的嵌套元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72406830/

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