C ++中具有std :: vector数据成员的constexpr成员函数

Luc*_*isi 23 c++ constexpr c++11

我试图在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;

}
Run Code Online (Sandbox Code Playgroud)

该代码可以使用命令正确编译

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’
Run Code Online (Sandbox Code Playgroud)

为什么代码不编译gcc -std=c++11而是编译clang++ -std=c++11?如何使此代码段与旧版本的gcc一起使用,而许多旧版本的gcc不支持c ++ 14/17,而仅支持c ++ 11?

我正在使用gcc 8.1.1和clang 6.0.1

rus*_*tyx 20

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;
  }
Run Code Online (Sandbox Code Playgroud)

现场演示