c++ - 左值引用对象 : Clang and gcc disagree 上的 Constexpr 成员函数

标签 c++ c++11 constexpr

当类具有 constexpr 成员函数并且该成员函数正在 constexpr 上下文中的左值对象上求值时,clang 和 gcc 不同意结果是否为 constexpr 值。 为什么?是否有既不需要默认可构造性也不需要复制可构造性的解决方法?

当对象按值传递时,两个编译器都编译成功。

Clang 版本 trunk、8、7:static_assert 表达式不是整数常量表达式

Gcc 版本 trunk、8.1、7.4:编译没有错误

#include <array>

using A = std::array<int, 10>;

void foo(const A& a){
    // clang: static_assert expression is not an integral constant expression
    static_assert(a.size() > 0, "");
}


void foo2(A a){
    // this compiles on both clang and gcc
    static_assert(a.size() > 0, "");
}

// Some custom code with the same symptom:
class B{
  public:
    constexpr int size()const{
        return 42;
    }
};

void foo3(const B& b){
    // clang: static_assert expression is not an integral constant expression
    static_assert(b.size() > 0, "");
}


void foo4(B b){
    // this compiles on both clang and gcc
    static_assert(b.size() > 0, "");
}

https://godbolt.org/z/9vmyli

有警告的解决方法:

void foo5(const B& b){
    // This works in clang, if the default constructor is defined
    static_assert(B().size() > 0, "");
}

void foo6(const B& b){
    // This works in clang, if the copy constructor is defined
    [](B b){static_assert(b.size() > 0, "");}(b);
}

最佳答案

core constant exprssions 的定义指定:

A core constant expression is any expression whose evaluation would not evaluate any one of the following:

...

  1. an id-expression referring to a variable or a data member of reference type, unless it was initialized with a constant expression or its lifetime began within the evaluation of this expression

...

所以你不能在这里引用const A& a

例如,以下代码片段编译良好:

using A = std::array<int, 10>;

constexpr A arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
constexpr const A& arr_ref = arr;   // OK: arr_ref is initialized with a constant expr

static_assert(arr.size() > 0, "");
static_assert(arr_ref.size() > 0, "");

关于c++ - 左值引用对象 : Clang and gcc disagree 上的 Constexpr 成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57779870/

相关文章:

c++ - 如何从引用中获取指针?

c++ - 为什么我解决N个皇后区问题的回溯解决方案不起作用?

c++ - 如何检查 C++ STL vector 中存在的值并将函数应用于 vector 的每个元素?

c++ - 哪些低级 Windows 特定函数用于在 Windows 中实现 std::thread/boost::thread/pthread?

c++ - 并发读取非原子变量

c++ - constexpr 重载

c++ - 使用用户定义的文字初始化 constexpr 数组

c++ - 检查两种类型在 C++ 中是否相等

c++ - 通过计算差异来反转字符串中各个字符的字母值