c++ - 通过引用传入的值的 constexpr

标签 c++ constexpr std-bitset

我有这段代码可以编译

#include <bitset>

struct A{
    std::bitset<50> b; };

void test(A a){
    static_assert(sizeof(int)*8 < a.b.size(), "can't accomodate int in bitset");
    int x = 5;
    a.b = x; }

int main(){
    A a;
    test(a); }

但这不是

#include <bitset>

struct A{
    std::bitset<50> b;
};

void test(A& a){
    static_assert(sizeof(int)*8 < a.b.size(), "can't accomodate int in bitset");
    int x = 5;
    a.b = x;
}

int main(){
    A a;
    test(a);
}

因出现此错误而失败

const.cpp: In function ‘void test(A&)’: const.cpp:8:5: error: non-constant condition for static assertion
     static_assert(sizeof(int)*8 < a.b.size(), "can't accomodate int in bitset");
const.cpp:8:5: error: ‘a’ is not a constant expression

为什么 a.b.size() 在第二种情况下不被视为 constexpr? std::bitset::size()constexpr 不是根据 reference 应该被视为 const 的那个吗? ?还是第二种情况下传递的非常量引用会触发编译器产生错误?

编译器版本: Ubuntu 14.0.4 上的 g++ 4.8.4,使用 g++ const.cpp -std=c++1y

编译

最佳答案

A& a 不能用在常量表达式中,使您的程序格式错误。

禁止 a.b.size() 为常量表达式且 aA& 的规则如下:

[expr.const]/3

A variable is usable in constant expressions after its initializing declaration is encountered if it is a constexpr variable, or it is of reference type or of const-qualified integral or enumeration type, and its initializer is a constant initializer.

在你的例子中,变量 a 是:

  • 未声明 constexpr(作为函数参数,没有意义),
  • 并且不是整数或枚举类型,
  • and 不是一个引用,它的初始化是一个常量初始化器:

[expr.const]/2

A constant initializer for a variable or temporary object o is an initializer for which interpreting its full-expression as a constant-expression results in a constant expression, except that if o is an object, such an initializer may also invoke constexpr constructors for o and its subobjects even if those objects are of non-literal class types.


采用以下简化示例:

struct s { constexpr static bool true_value() { return true; } };
void assert_on(s const& ref)
{
    static_assert(ref.true_value());
}

int main()
{
    assert_on(s{});
}

gcc-9 错误地接受它1,但 clang-8 产生正确的诊断:

error: static_assert expression is not an integral constant expression

完整演示:https://godbolt.org/z/t_-Ubj


1) 这是 GCC bug #66477 , 从 5.1 版开始激活,尚未解决。

关于c++ - 通过引用传入的值的 constexpr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57196229/

相关文章:

c++ - 为什么 constexpr 应该是静态的?

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

c++ - 如何将 C++ 位集中的位范围子集转换为数字?

java - 在文件中从 Java 编写 Long 并在 C++ 中读取它

c++ - 由于模板基类,从不完整类型初始化静态 constexpr

c++ - CUDA *.obj 文件不被 Visual Studio 链接器处理

c++ - Bitset 作为函数的返回值

c++ - 我正在使用 std::bitset 并尝试创建两个大小为 100,000,000,000 的数组 std::bitset

c++ - 在使用不同的 visual studio 编译器版本编译的进程中加载​​ COM

c++ - VC9 中的字符串流错误? "Cannot access private member"