在 C++ 中的类声明中初始化 const 成员
在 PHP 和 C# 中,常量可以在声明时进行初始化:
class Calendar3
{
const int value1 = 12;
const double value2 = 0.001;
}
我有以下函子的 C++ 声明,该函子与另一个类一起使用来比较两个数学向量:
struct equal_vec
{
bool operator() (const Vector3D& a, const Vector3D& b) const
{
Vector3D dist = b - a;
return ( dist.length2() <= tolerance );
}
static const float tolerance = 0.001;
};
此代码使用 g++ 编译时没有问题。现在,在 C++0x 模式 (-std=c++0x) 下,g++ 编译器输出一条错误消息:
错误:非整数类型的静态数据成员“tolerance”的类内初始化需要“constexpr”
我知道我可以在类定义之外定义和初始化这个static const
成员。此外,非静态常量数据成员可以在构造函数的初始化列表中初始化。
但是有什么方法可以像在 PHP 或 C# 中一样在类声明中初始化常量吗?
更新
我使用 static
关键字只是因为可以在 g++ 的类声明中初始化此类常量。我只需要一种方法来初始化类声明中的常量,无论它是否声明为静态。
In PHP and C# the constants can be initialized as they are declared:
class Calendar3
{
const int value1 = 12;
const double value2 = 0.001;
}
I have the following C++ declaration of a functor which is used with another class to compare two math vectors:
struct equal_vec
{
bool operator() (const Vector3D& a, const Vector3D& b) const
{
Vector3D dist = b - a;
return ( dist.length2() <= tolerance );
}
static const float tolerance = 0.001;
};
This code compiled without problems with g++. Now in C++0x mode (-std=c++0x) the g++ compiler outputs an error message:
error: ‘constexpr’ needed for in-class initialization of static data member ‘tolerance’ of non-integral type
I know I can define and initialize this static const
member outside of the class definition. Also, a non-static constant data member can be initialized in the initializer list of a constructor.
But is there any way to initialize a constant within class declaration just like it is possible in PHP or C#?
Update
I used static
keyword just because it was possible to initialize such constants within the class declaration in g++. I just need a way to initialize a constant in a class declaration no matter if it declared as static
or not.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
初始化 const int 类型以外的静态成员变量不是 C++11 之前的标准 C++。除非您指定
-pedantic
选项,否则 gcc 编译器不会就此发出警告(并且仍然会生成有用的代码)。然后,您应该收到类似以下内容的错误:原因是 C++ 标准没有指定如何实现浮点,而是由处理器决定。为了解决这个问题和其他限制,引入了
constexpr
。Initializing static member variables other than const int types is not standard C++ prior C++11. The gcc compiler will not warn you about this (and produce useful code nonetheless) unless you specify the
-pedantic
option. You then should get an error similiar to:The reason for this is that the C++ standard does not specifiy how floating point should be implemented and is left to the processor. To get around this and other limitations
constexpr
was introduced.是的。只需按照错误提示添加
constexpr
关键字即可。Yes. Just add the
constexpr
keyword as the error says.我遇到了真正的问题,因为我需要使用相同的代码来使用不同版本的 g++(GNU C++ 编译器)进行编译。所以我必须使用宏来查看正在使用哪个版本的编译器,然后采取相应的操作,就像这样
这将对 g++ 6.0.0 版之前的所有内容使用“const”,然后对 g++ 6.0 版使用“constexpr”。 0及以上。这是对发生更改的版本的猜测,因为坦率地说,直到 g++ 6.2.1 版本我才注意到这一点。为了正确执行此操作,您可能需要查看 g++ 的次要版本和补丁号,因此请参阅
https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
了解可用宏的详细信息。
使用 gnu,您还可以坚持在任何地方使用“const”,然后使用
-fpermissive
标志进行编译,但这会发出警告,而且我喜欢干净地编译我的东西。不太好,因为它特定于 gnu 编译器,但我怀疑您可以对其他编译器执行类似的操作。
I ran into real problems with this, because I need the same code to compile with differing versions of g++ (the GNU C++ compiler). So I had to use a macro to see which version of the compiler was being used, and then act accordingly, like so
This will use 'const' for everything before g++ version 6.0.0 and then use 'constexpr' for g++ version 6.0.0 and above. That's a guess at the version where the change takes place, because frankly I didn't notice this until g++ version 6.2.1. To do it right you may have to look at the minor version and patch number of g++, so see
https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
for the details on the available macros.
With gnu, you could also stick with using 'const' everywhere and then compile with the
-fpermissive
flag, but that gives warnings and I like my stuff to compile cleanly.Not great, because it's specific to gnu compilers, butI suspect you could do similar with other compilers.
如果您只在一个方法中需要它,您可以将其声明为本地静态:
If you only need it in the one method you can declare it locally static:
在 C++11 中,整型或枚举类型的非
static
数据成员、static constexpr
数据成员和static const
数据成员可以是在类声明中初始化。例如,在本例中,类
X
的所有实例的i
成员由编译器生成的构造函数初始化为5
,并且>f
成员初始化为3.12
。static const
数据成员j
初始化为42
,static constexpr
数据成员g< /code> 初始化为
9.5
。由于
float
和double
不是整型或枚举类型,因此此类成员必须是constexpr
或非static
> 为了允许类定义中的初始值设定项。在 C++11 之前,只有整型或枚举类型的
static const
数据成员可以在类定义中具有初始值设定项。In C++11, non-
static
data members,static constexpr
data members, andstatic const
data members of integral or enumeration type may be initialized in the class declaration. e.g.In this case, the
i
member of all instances of classX
is initialized to5
by the compiler-generated constructor, and thef
member is initialized to3.12
. Thestatic const
data memberj
is initialized to42
, and thestatic constexpr
data memberg
is initialized to9.5
.Since
float
anddouble
are not of integral or enumeration type, such members must either beconstexpr
, or non-static
in order for the initializer in the class definition to be permitted.Prior to C++11, only
static const
data members of integral or enumeration type could have initializers in the class definition.