C++11 - constexpr 上的 bad_alloc

标签 c++ c++11 constexpr

带位掩码的数组真的很流行,通常它们写起来很乏味,而且它们使代码的可读性降低,我想用 constexpr 生成它们,这是我的尝试

#include <iostream>
#include <cstdint>
#include <vector>
#include <utility>

typedef uint32_t myT;

template <typename T>
constexpr std::vector<T> vecFarm(T &&lower, T &&upper, T &&step) {
  // std::cout << lower << " " << upper << " " << step << "\n";
  std::vector<T> v;
  if (lower < upper) {
    for (T count = lower; count < upper; count += step) {
      v.push_back(count);
    };
  }
  return (v);
}

int main() {

  std::vector<myT> k(std::move(vecFarm(myT(0), ~(myT(0)), myT(256)))); //why
  // this doesn't work ?
  // std::vector<myT> k(std::move(vecFarm(myT(0), ((~(myT(0))) >> 16), myT(256))));
  // but this one works
  // let's see what we got
  for (const auto &j : k) {
    std::cout << j << " ";
  }
  std::cout << "\n";

  return (0);
}

我使用了std::move、未命名的对象和一个constexpr,这段代码可以很好地编译

g++-4.8 -O3 -std=c++11 -pthread -Werror -Wall -Wextra

但由于 bad_alloc,它在运行时失败了,我可以看到我的“小”应用程序分配了大量空间。

也许错误很大,我看不到,但为什么这不起作用?

为什么我的应用程序在运行时进行分配?不应该在编译时计算所有内容吗?我原以为这可能会在编译时失败,而不是在运行时。

最佳答案

std::bad_alloc通常意味着它不能分配更多的内存。将您的代码更改为以下内容将告诉您原因:

for (T count = lower; count < upper; count += step) {
    std::cout << "count:" << count << "\n";
    std::cout << "upper:" << upper << "\n";
};

当我测试它时,这会在第一个循环中打印以下内容:

count:0
upper:4294967295

也就是说,在count < upper之前你还有很长的路要走失败并且 for 循环停止,特别是因为您只添加了 256每次。

此外,为了 constexpr要在编译时评估的函数,有某些 conditions it has to fullfil .例如,its return type must be LiteralType , 你的函数返回 std::vector , 还有, exactly one return statement that contains only literal values, constexpr variables and functions.你有一个复合语句。因此,您的函数无法在编译时求值。

另请注意,如果您不满足这些条件,constexpr限定符将被忽略,尽管如果您打开 -pedantic它应该可以为您提供更好的诊断。

关于C++11 - constexpr 上的 bad_alloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20028143/

相关文章:

c++ - 从多个线程调用 WSAStartup() 会导致死锁吗?

c++ - 这个使用 decltype 和 declval 的 C++ typedef 应该如何编写以使其可移植?

c++ - 可以比较 std::type_info 上的指针是否在常量表达式中相等?

c++ - 避免在 C++20 中进行互斥函数调用的预处理器

c++ - 为什么 lambda 没有从到达范围捕获类型 const double,而 const int 是?

c++ - 如何将 std::string_view 转换为 const char*?

c++ - 如何使用函数名作为参数?

c++ - 重载指针的右值/常量左值

c++ - 显式删除移动构造函数

c++ - 在 log(n) 时间内获取指向已排序 vector 中元素的迭代器。