constexpr 成员函数,C++中的 std::向量数据成员

constexpr member function with std::vector data member in C++

本文关键字:std 向量 数据成员 中的 C++ 成员 函数 constexpr      更新时间:2023-10-16

我正在尝试在C++类中实现一个返回模板参数的constexpr成员函数。代码应该是 c++11 兼容的。但是,当模板化类还包含 STL 容器作为数据成员(如 std::vector(时,我遇到了编译问题(constexpr 成员函数未触及这些容器(。

以下代码给出了一个最小示例:

#include <vector>
#include <iostream>
#include <array>
template<size_t n>
struct A 
{
    constexpr size_t dimensions() const
    {
        return n;
    }
private:
    std::vector<double> a;
};
 
int main(int argc,char ** argv)
{
    auto a=A<3>();
    std::array<double,a.dimensions()> arr;
}

代码使用命令正确编译

g++ -std=c++14 -O3 quickTest.cpp -o test -Wall

clang++ -std=c++11 -O3 quickTest.cpp -o test -Wall

但在我使用 时失败

g++ -std=c++11 -O3 quickTest.cpp -o test -Wall

出现错误:

quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
   std::array<double,a.dimensions()> arr;
                     ~~~~~~~~~~~~^~
quickTest.cpp:10:20: note: ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’ is not usable as a ‘constexpr’ function because:
   constexpr size_t dimensions() const
                    ^~~~~~~~~~
quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
   std::array<double,a.dimensions()> arr;
                     ~~~~~~~~~~~~^~
quickTest.cpp:22:33: note: in template argument for type ‘long unsigned int’

为什么代码不用gcc -std=c++11编译,而是用clang++ -std=c++11编译?如何使此代码片段适用于可能不支持 c++14/17 而仅支持 c++11 的旧版本的 gcc?

我正在使用 gcc 8.1.1 和 clang 6.0.1

C++11 有一个规则 [dcl.constexpr]/8:

。该函数所属的类应为文本类型 ([basic.types](。

struct A不是文字类型,因为vector,因此它的非静态成员函数不能constexpr

因此,GCC 在 C++11 模式下拒绝代码是正确的。

C++14取消了这一限制。

C++11 的解决方案是声明dimensions() static

static constexpr size_t dimensions()
{
    return n;
}

现场演示