【问题标题】:C++ Force non constexpr contextC++ 强制非 constexpr 上下文
【发布时间】:2019-06-13 10:30:03
【问题描述】:

我有使用 constexpr 说明符声明的函数,并且我已经测试过它们在单元测试的编译时被评估。

现在我想在我的单元测试中使用消毒剂来发现更多问题。但是因为我的很多函数都是用constexpr 指定的,所以我不确定该怎么做,因为如果在编译时评估一个函数,那么消毒剂是否无用?

有没有办法强制constexpr 函数在编译时不被评估。 或者你有什么其他的建议。

【问题讨论】:

  • GCC、Clang 和 MSVC 似乎都不会在未优化的构建(以及调试构建)中在编译时评估 constexpr 函数,除非它们在编译时的上下文中使用常量是必需的。

标签: c++ c++11 metaprogramming constexpr


【解决方案1】:

有没有办法强制 constexpr 函数在编译时不被评估 [?]

如果您可以修改constexpr 函数,添加一个未使用的参数,您可以强制运行时评估传递一个运行时值。

我的意思是...假设您有以下constexpr 函数

constexpr int getVal ()
 { return 0; }

你可以如下使用它

constexpr auto a = getVal();

auto b = getVal();

并且(忽略“原样”规则)您确定 getVal() 是计算编译时初始化 a 但您不知道它是计算编译时还是运行时初始化 b .

但是如果你修改函数如下

constexpr int getVal (int)
 { return 0; }

你可以写

   int c = 1;

   constexpr auto a = getVal(0);

   auto b = getVal(c);

现在您可以确信 getVal() 是计算编译时初始化 a (因为 aconstexpr 并且 0 是一个文字)并且这是计算运行时初始化 b(因为c 不能在constexpr 表达式中使用)。

你也可以验证写作

int c = 1;

constexpr auto a = getVal(c);

您会收到一个编译错误,因为 a 必须在编译时初始化,但 getVal(c) 不能在编译时计算。

【讨论】:

    【解决方案2】:

    有没有办法强制 constexpr 函数在编译时不被评估。

    constexpr 告诉编译器该函数及其调用的任何东西都应该是安全的。你不能做的一件事是newdelete。对constexpr 的限制意味着可以隐式避免大量使用消毒剂设计的陷阱。

    或者你有什么其他的建议。

    消毒剂仍然有用。例如,您可以调用未定义的行为。仅仅因为你的很多代码是 constexpr 并不意味着不是的位也是隐式安全的。

    【讨论】:

      猜你喜欢
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 2017-01-05
      • 2013-07-13
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多