【问题标题】:C++: cast array/vector integer element to constexprC++:将数组/向量整数元素转换为 constexpr
【发布时间】:2020-12-08 19:46:33
【问题描述】:

我真的无法在任何地方在线找到解决方案。在 C++11 之前,我有点像恐龙,我无法确定要对 constexpr 进行类型转换。

有谁知道如何将 C 风格的数组和/或 std::vector(整数)元素转换为 constexpr

也就是说,让我们说

int a[]={1,2};
vector<int> v={1,2};

如何将a[1]v[1] 转换为constexpr

constexpr int b=a[1];

例如,编译器会在 for 循环中报错。

error: the value of ‘a’ is not usable in a constant expression
     constexpr int b=a[i];

我目前几乎没有想法。谢谢

【问题讨论】:

  • 你不能。只有constant expressions 可以分配给constexpr 变量。
  • 你需要一台时间机器来将一个仅在运行时知道的值转换为在编译时已知的值
  • 你不能,请查看 cppreference (en.cppreference.com/w/cpp/language/constexpr) "一个 constexpr 变量必须满足以下要求:它的类型必须是 LiteralType。它必须立即初始化它的完整表达式初始化,包括所有隐式转换、构造函数调用等,必须是常量表达式“
  • AdabH,我刚刚做到了。哇.. 自 2017 年以来情况发生了很大变化...
  • 您能告诉我们您通过将动态值转换为 constexpr 来解决什么问题吗?

标签: c++ arrays c++11 constexpr


【解决方案1】:

建议:如果可以的话至少可以用C++14,而不是std::vector,如果可以的话, 使用std::array

声明constexpr

#include <array>

int main () 
 {
   constexpr std::array<int, 2u> a {1, 2};

   constexpr auto b = a[1];
 }

std::array 是与constexpr 兼容的类型,所以它是operator[]()const 版本),或者它也是at() 方法(const 版本)。

C++14 是必需的,因为在 C++11 中 std::array::operator[]() conststd::array::at() const 不是 constexpr 方法,因此不能在常量表达式中使用。

不幸的是,std::vector 需要分配内存,因此与constexpr 不兼容(在 C++20 之前)。

对于 C 风格的数组情况,您只需声明它constexpr

int main () 
 {
// VVVVVVVVV   
   constexpr int a[] = {1,2};

   constexpr auto b = a[1];
 }

【讨论】:

  • @idclev463035818 - 为什么不呢?完成。
  • 好吧,这看起来很有希望。有没有办法泛化到 a[i],还是索引必须定义好?
  • @SjL - 显然索引也必须是一个常量表达式;所以constexpr auto index = 0u; constexpr auto b = a[index]; 有效,auto index = 0u; constexpr auto b = a[index]; 无效。
  • 我明白了,如果我想在 for 循环中迭代它,你有什么建议吗?
  • @SjL - 如果你只知道可变参数模板的使用......我通常会通过一个接受std::index_sequence 的辅助函数(包含作为模板值的索引,因此是一系列常量表达式) 并使用std::make_index_sequence 调用它(生成索引的模板序列)。
【解决方案2】:

constexpr 必须有一个常量表达式,即它们必须在编译时已知。您不能使用ab 执行分配,在这种情况下这是一个错误。

在给定的代码 sn-p 中,a 没有定义为 constexpr,因此,它没有明确告诉编译器该表达式是一个常量。

【讨论】:

  • 但是a 在编译时是“已知的”,或者更确切地说,我们在编译时就知道它的内容。请向 OP 解释为什么这还不够。
猜你喜欢
  • 2018-06-26
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2012-12-11
  • 2012-05-10
  • 2019-07-21
  • 1970-01-01
  • 2012-10-09
相关资源
最近更新 更多