如何在编译时查询 constexpr std::tuple?

发布于 2024-10-18 14:18:52 字数 926 浏览 2 评论 0原文

在 C++0x 中,可以创建一个 constexpr std::tuple,例如,

#include <tuple>
constexpr int i = 10;
constexpr float f = 2.4f;
constexpr double d = -10.4;
constexpr std::tuple<int, float, double> tup(i, f, d);

也可以在运行时查询 std::tuple,例如 via

int i2 = std::get<0>(tup);

但不可能在编译时查询它,例如,

constexpr int i2 = std::get<0>(tup);

会抛出编译错误错误(至少对于最新的 g++ 快照 2011-02-19)。

是否有其他方法可以在编译时查询 constexpr std::tuple?

如果没有,是否存在不应该查询它的概念原因?

(我知道避免使用 std::tuple,例如,通过使用 boost::mpl 或 boost::fusion 代替,但不知怎的,不使用 tuple 类听起来是错误的 在新标准中...)。

顺便问一下,有人知道为什么

  constexpr std::tuple<int, float, double> tup(i, f, d);

编译得很好,但编译

  constexpr std::tuple<int, float, double> tup(10, 2.4f, -10.4);

不行吗?

预先非常感谢! - 拉斯

In C++0x, one can create a constexpr std::tuple, e.g. like

#include <tuple>
constexpr int i = 10;
constexpr float f = 2.4f;
constexpr double d = -10.4;
constexpr std::tuple<int, float, double> tup(i, f, d);

One also can query a std::tuple at runtime, e.g. via

int i2 = std::get<0>(tup);

But it is not possible to query it at compile time, e.g.,

constexpr int i2 = std::get<0>(tup);

will throw a compilation error (at least with the latest g++
snapshot 2011-02-19).

Is there any other way to query a constexpr std::tuple at compile time?

And if not, is there a conceptual reason why one is not supposed to query it?

(I am aware of avoiding using std::tuple, e.g., by using boost::mpl
or boost::fusion instead, but somehow it sounds wrong not to use the tuple class
in the new standard...).

By the way, does anybody know why

  constexpr std::tuple<int, float, double> tup(i, f, d);

compiles fine, but

  constexpr std::tuple<int, float, double> tup(10, 2.4f, -10.4);

not?

Thanks a lot in advance!
- lars

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

陈甜 2024-10-25 14:18:52

std::get 未标记 constexpr,因此您无法使用它从 constexpr 中的 tuple 检索值code> 上下文,即使该元组本身就是 constexpr

不幸的是,std::tuple 的实现是不透明的,因此您也无法编写自己的访问器。

std::get is not marked constexpr, so you cannot use it to retrieve the values from a tuple in a constexpr context, even if that tuple is itself constexpr.

Unfortunately, the implementation of std::tuple is opaque, so you cannot write your own accessors either.

夏夜暖风 2024-10-25 14:18:52

现在, std::get<>是一个 constexpr 函数。如果我使用 gcc c++ 11 或更高版本,则可以编译以下代码。

constexpr int i2 = std::get<0>(tup);
constexpr std::tuple<int, float, double> tup(10, 2.4f, -10.4);

此外,您可以使用 make_index_sequence (c++14 或更高版本)在编译时生成数字列表并访问元组。

constexpr auto size = std::tuple_size<decltype(tup)>::value;
for_sequence(std::make_index_sequence<size>{}, [&](auto i){
        constexpr auto property = std::get<i>(tup);
        std::cout<<property<<std::endl;
});

template <typename T, T... S, typename F>
constexpr void for_sequence(std::integer_sequence<T, S...>, F&& f) {
    using unpack_t = int[];
    (void)unpack_t{(static_cast<void>(f(std::integral_constant<T, S>{})), 0)..., 0};
}

Now, std::get<> is a constexpr function. The following code compiles for me if I use gcc c++ 11 or above.

constexpr int i2 = std::get<0>(tup);
constexpr std::tuple<int, float, double> tup(10, 2.4f, -10.4);

Furthermore, you can generate a list of numbers at compile time by using make_index_sequence (c++14 or above) and access the tuple.

constexpr auto size = std::tuple_size<decltype(tup)>::value;
for_sequence(std::make_index_sequence<size>{}, [&](auto i){
        constexpr auto property = std::get<i>(tup);
        std::cout<<property<<std::endl;
});

template <typename T, T... S, typename F>
constexpr void for_sequence(std::integer_sequence<T, S...>, F&& f) {
    using unpack_t = int[];
    (void)unpack_t{(static_cast<void>(f(std::integral_constant<T, S>{})), 0)..., 0};
}
暗藏城府 2024-10-25 14:18:52

此问题已在 c++17 中修复。但是如果您想将元组作为参数传递到 constexpr 函数中,我强烈建议您阅读这篇文章 https://mpark.github.io/programming/2017/05/26/constexpr-function-parameters/

This issue was fixed in c++17. But if you want to pass tuple into the constexpr function as a parameter, i would strongly recommend to read this post https://mpark.github.io/programming/2017/05/26/constexpr-function-parameters/

吖咩 2024-10-25 14:18:52

我还没有使用过 C++0x,但在我看来 std::get() 是一个函数,而不是编译器可以直接解释的表达式。因此,除了在函数本身被编译之后的运行时之外,它没有任何意义。

I have not yet worked with C++0x, but it seems to me that std::get() is a function, rather than expression the compiler can directly interpret. As such, it has no meaning except at runtime, after the function itself has been compiled.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文