C++ 为什么不';t std::constexpr算法,哪一个可能是?

C++ 为什么不';t std::constexpr算法,哪一个可能是?,c++,algorithm,c++14,constexpr,C++,Algorithm,C++14,Constexpr,为什么没有任何std::algorithm方法constexpr?如果我正确理解新的C++14规则,其中许多方法可能是constexpr。例如,为什么不能std::findbeconstexpr static constexpr std::array<char, 4> DnaBases {'A', 'C', 'G', 'T'}; constexpr bool is_dna(char b) { return std::find(std::cbegin(DnaBases), s

为什么没有任何
std::algorithm
方法
constexpr
?如果我正确理解新的C++14规则,其中许多方法可能是
constexpr
。例如,为什么不能
std::find
be
constexpr

static constexpr std::array<char, 4> DnaBases {'A', 'C', 'G', 'T'};

constexpr bool is_dna(char b)
{
    return std::find(std::cbegin(DnaBases), std::cend(DnaBases), b) != std::cend(DnaBases); // why not?
}
static constepr std::数组数据库{'A','C','G','T'};
constexpr bool是_dna(字符b)
{
返回std::find(std::cbegin(DnaBases),std::cend(DnaBases),b)!=std::cend(DnaBases);//为什么不呢?
}

其他哪些
std::algorithm
s可以是
constepr

它可以是
constepr
,但不能作为常量表达式计算,因为在这种情况下,例如对于编译时查找,需要:
static constexpr std::array<char, 4> DnaBases {'A', 'C', 'G', 'T'};

constexpr bool is_dna(char b)
{
    return std::find(std::cbegin(DnaBases), std::cend(DnaBases), b) != std::cend(DnaBases); // why not?
}
开始/结束
应该是constexpr,迭代器的
*运算符
应该是constexpr,
运算符==
应该是constexpr,
运算符=应该是constexpr,迭代器的
操作符+
应该是constexpr。但是,如果所有函数都是
constexpr
,那么许多算法都可以用
constexpr
实现

您可以查看constexpr容器/算法的实现


基于
constexpr
-ness,不能重载有关函数的相关讨论。因此,任何定义为
constexpr
的函数都需要以
constexpr
的形式实现。此要求对所有实现施加了约束

与C++11相比,C++14规范在约束方面有些宽松。然而,当规范最终确定时,没有人相信当算法被强制为
constepr
时,可以实现没有
constepr
约束的所有优化。在不知道非
constexpr
功能不会因强制
constexpr
实现而受到阻碍的情况下,不会将算法定义为
constexpr
。算法的非
constexpr
使用仍然被认为是算法的主要用途


拥有一套定义为
constexpr
的特殊算法可能是值得的。我不知道有相应的建议。我也看不出有多少需求需要标准化,但我的看法可能与其他人不同。

std::algorithm
算法作用于迭代器。使它们成为
constexpr
通常会阻止编译它们(在C++11中)或什么都不做(在C++14中或使用条件-
constexpr
),这有一个技术原因,但也有一个语义原因,说明它们成为
constexpr
没有意义

技术原因是
constepr
函数不能调用非
constepr
表达式。ForEveR指出,如果模板
constexpr
函数调用非
constexpr
表达式,则无法在编译时对其求值

std::algorithm
的情况下,评估
std::algorithm
中的
constexpr
函数将要求访问容器迭代器的函数为
constexpr
,这反过来又要求迭代器本身为
constexpr
类型。但从定义上来说,这几乎是不可能的;容器通常被设计为对堆分配内存的轻量级访问,但堆内存不能在编译时分配(当然)。在下面的评论中,dyp指出迭代器并不总是指向容器,但即使是这些迭代器也不可能在编译时可用;例如,streams对象在编译时当然不可读写,因为IO不能在编译时完成

这导致了语义问题:
constepr
语义上意味着函数可以在编译时进行计算。当无法在编译时对函数求值时,有条件地声明函数-
constexpr
,会使API混淆和误导

现在,我认为如果有一种在编译时创建和使用容器的方法,语言将会得到改进这将使
constexpr
与Lisp的宏功能更加相似。这可能最终会被添加,但目前它并没有得到现有标准库代码的真正支持。如上所述,最灵活的方法是允许某些对象在编译时驻留在堆上,而核心语言根本不支持这种方法,这将导致一些严重的复杂性。例如,对这些物体做什么是合法的?要么它们的生命周期只需要限制在编译时,要么它们需要作为静态常量内存包含在最终程序中(如字符串文字),要么……什么?

当前的(C++14)标准库是与
constexpr
相关的相应核心语言功能的w.r.t

例如,MSVC 2015,它只有C++11语言支持
constexpr
,整个C++14标准库使用
constexpr
。唯一的例外是
std::min
std::max
std::minmax
std::min_元素
std::max_元素
std::minmax_元素
对于
std::initializer_列表

从C++1z(17?)开始,
std::xxx_元素
算法将成为通用迭代器和比较器输入的
constepr
算法,以统一
std::initializer_列表
的用法。此外,还有用于C++1z的函数

随着lambdas的升级,仍然存在一些核心语言限制,通过允许编译器对其求值来阻止整个

  • 有些算法是动态的