相关疑难解决方法(0)

为什么constexpr在适用时不暗示?

这些可能应该是在不同的问题,但它们是相关的......

  1. 为什么我们需要写constexpr?鉴于一组限制,编译器无法评估代码以确定它是否满足constexpr要求,并将其视为constexpr是否满足要求?作为一个纯粹的文档关键字,我不确定它是否成立,因为我无法想到我(其他人的constexpr功能的用户)应该真正关心它是否运行时的情况.

    这是我的逻辑:如果它是一个昂贵的函数,我认为作为一个良好的实践,我应该这样对待它,无论我是否给它编译时常量输入.这可能意味着在加载时调用它并保存结果,而不是在执行的关键点调用它.原因是因为constexpr实际上并没有向我保证它不会在运行时首先执行 - 所以也许一个新的/不同的机制应该这样做.

  2. 这些constexpr限制似乎排除了许多(如果不是大多数)函数的编译时评估,逻辑上可能是这样.我已经读过这至少部分(或者可能完全是?)来防止无限循环并挂起编译器.但是,如果这是原因,是合法的?

对于constexpr使用给定输入的任何给定函数,编译器是否应该能够计算它是否无限循环?这不是解决停机问题任何输入.constexpr函数的输入是编译时常量和有限,因此编译器只需检查有限输入的无限循环:实际使用的输入.如果编写编译时无限循环,则应该是常规编译错误.

c++ constexpr c++11

14
推荐指数
1
解决办法
389
查看次数

为什么constexpr不能成为默认值?

constexpr 允许在编译时评估的表达式在编译时进行评估.

为什么这个关键字是必要的?为什么不允许或要求编译器在编译时评估所有表达式?

标准库有一个不均匀的constexpr应用程序,这会带来很多不便.使constexpr成为"默认"将解决这个问题,并可能改进大量现有代码.

c++

13
推荐指数
2
解决办法
713
查看次数

为什么constexpr适用于不纯的功能

在浏览constexpr的一个旧问题时,我偶然发现了一个非常(恕我直言)的重要评论.基本上归结为:(这是合法的C++ 11 :()

 constexpr double f(bool b)
 {
 return b? 42:42/(rand()+1); // how pure is rand ;)
 }
Run Code Online (Sandbox Code Playgroud)

我的问题是标准允许这是什么原因.由于我是参考透明度的忠实粉丝,我希望他们有充分的理由:)我想知道.

顺便说一下,有相关的Q但是大多数A甚至都不提纯东西,或者当他们这样做时,他们没有指明为什么std允许这个的原因. constexpr与纯函数之间的关系

c++ constexpr c++11

12
推荐指数
3
解决办法
605
查看次数

为什么constexpr不是所有功能的默认值?

在放宽constexpr的规则之后,似乎这些功能可以在任何地方使用.它们也可以在常量(constexpr)和局部(可变)变量上调用.所以对我来说,它似乎只是编译器的一个提示(如内联).我只是继续在任何地方写它并在编译器抱怨时删除它.因此,如果可以在编译时评估函数,编译器似乎知道所有内容.为什么它不是默认行为,为什么我必须将任何东西标记为constexpr?

c++ constexpr c++14

10
推荐指数
1
解决办法
1036
查看次数

Constexpr lambda默认情况下?

根据n4487和其他c ++ 17引用,将会有新的lambda函数说明符 - constexpr如果存在,则"明确指定函数调用运算符是一个constexpr函数." .我理解lambda中常量表达式的动机.对我来说有趣的是提案的第4点,其中指出:

4)如果constexpr在lambda声明符中省略了说明符,则函数调用运算符(或模板)constexpr是否满足constexpr函数的要求.

这引出了两个问题:

  1. 为什么我们需要constexpr说明符?看起来lambda调用操作符是否将constexpr取决于它"满足constexpr函数的要求"的事实,而不是来自 constexpr说明符的存在.
  2. 如果constexpr默认情况下可以接受lambda,那么为什么不建议其他类型的函数 - 例如全局函数?如果编译器开始处理涵盖需求的所有函数,会产生什么影响constexpr

c++ lambda constexpr c++17

10
推荐指数
1
解决办法
638
查看次数

鉴于 C++23 对 constexpr 的放宽,constexpr 不能成为默认值吗?

关键字constexpr在引入 C++11 标准时对其函数实施了相当严格的限制。C++14 和 C++20 放宽了这些限制(最值得注意):

  • C++14 允许多个return语句static_assert等。
  • C++20 允许try并且asm

C++23 进一步软化了这些限制。从我在cppreference中看到的,constexprfor函数似乎只剩下以下含义:

  • 它不能是协程
  • 对于构造函数和析构函数,该类必须没有虚拟基类
  • 对于 constexpr 函数模板和类模板的 constexpr 成员函数,至少一种特化必须满足上述要求。

C++23 甚至删除了 constexpr 函数必须在编译时对于p2448r2中的任何类型“可计算”的限制。根据我的理解,这完全消除了constexpr在编译时评估函数的想法。

是这样吗?如果是这样,constexpr函数还有什么用处呢?

c++ language-design constexpr constexpr-function c++23

8
推荐指数
1
解决办法
1100
查看次数

为什么 constexpr 不是自动的?

据我所知, constexpr 可以被视为编译器的提示,以检查是否可以在编译时评估给定的表达式,并在可能的情况下进行评估。

我知道它也对声明为 constexpr 的函数或初始化施加了一些限制,但最终目标是编译时评估,不是吗?

所以我的问题是,为什么我们不能把它留给编译器呢?它显然能够检查前置条件,那么为什么它不对每个表达式进行检查并在可能的情况下在编译时进行评估呢?

关于为什么会这样,我有两个想法,但我还不确定它们是否达到了目的:

a) 在编译期间可能需要太长时间。

b) 由于我的代码可以在不允许 normale 函数的位置使用 constexpr 函数,因此说明符也是声明的一部分。如果编译器自己完成所有事情,则可以使用 C 数组定义中的函数和该函数的一个版本,但在下一版本中可能会出现编译器错误,因为编译时评估的前提条件是不比较满意。

c++ constexpr c++11

5
推荐指数
1
解决办法
645
查看次数

constexpr、consteval 和 constinit 作为定义而不是关键字就足够了吗?

编译时关键字: 和 的规则似乎constexpr已经consteval定义constinit得足够好,编译器可以在您误用标签时发出警告。

这是有道理的(很像内联)编译器可以在所有地方应用规则来确定代码实际上是否可以应用编译时关键字之一,并且根据语言规范强制编译为尽可能就像应用了编译时关键字一样。

或者,至少,如果将编译时关键字应用于函数,并且如果应用了正确的编译时关键字,则代码将具有资格。编译该函数,就好像所有调用的函数都具有正确的编译时关键字一样。

这是一个简单的例子:

#include <tuple>

consteval std::tuple<int, int> init1(int x, int y)
{
    return {x,y};
}

std::tuple<int, int>& foo1()
{
    static constinit std::tuple<int, int> x=init1(1,2);
    return x;
}

std::tuple<int, int> init2(int x, int y)
{
    return {x,y};
}

std::tuple<int, int>& foo2()
{
    static std::tuple<int, int> x=init2(1,2);
    return x;
}

static std::tuple<int, int> x3=init2(1,2);

std::tuple<int, int>& foo3()
{
    return x3;
}
Run Code Online (Sandbox Code Playgroud)

在这里查看: https: //godbolt.org/z/KrzGfnEo7

请注意,init1/foo1 是用编译时关键字完全指定的,并且不需要保护变量,因为它已完全初始化(而不仅仅是填充 0)。

问题是为什么编译器在 init2/foo2 或 x3/foo3 的情况下不做同样的事情?或者更准确地说,为什么不允许编译器在编译时完全初始化。 …

c++ language-lawyer c++20

5
推荐指数
1
解决办法
247
查看次数