C++ 中具有 std::vector 数据成员的 constexpr 成员函数
constexpr member function with std::vector data member in C++
我正在尝试在 C++ 中实现 class 一个 constexpr 成员函数,其中 returns 一个模板参数。该代码应该是 c++11 兼容的。但是,当模板化 class 还包含 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
编译?
如何使此代码片段与旧版本的 gcc 一起工作,其中许多不支持 c++14/17,但仅支持 c++11?
我正在使用 gcc 8.1.1 和 clang 6.0.1
C++11 有一条规则 [dcl.constexpr]/8:
... The class of which that function is a member shall be a literal type ([basic.types]).
struct A
不是 文字类型 因为 vector
,因此它的非静态成员函数不能是 constexpr
.
所以GCC拒绝C++11模式下的代码是对的。
C++14 removed那个限制。
C++11 的解决方案是声明 dimensions()
static
:
static constexpr size_t dimensions()
{
return n;
}
我正在尝试在 C++ 中实现 class 一个 constexpr 成员函数,其中 returns 一个模板参数。该代码应该是 c++11 兼容的。但是,当模板化 class 还包含 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
编译?
如何使此代码片段与旧版本的 gcc 一起工作,其中许多不支持 c++14/17,但仅支持 c++11?
我正在使用 gcc 8.1.1 和 clang 6.0.1
C++11 有一条规则 [dcl.constexpr]/8:
... The class of which that function is a member shall be a literal type ([basic.types]).
struct A
不是 文字类型 因为 vector
,因此它的非静态成员函数不能是 constexpr
.
所以GCC拒绝C++11模式下的代码是对的。
C++14 removed那个限制。
C++11 的解决方案是声明 dimensions()
static
:
static constexpr size_t dimensions()
{
return n;
}