一个关于const和constexpr的疑惑

levonsoft 2020-07-17 02:47:57
一个关于const和constexpr的疑惑
代码如下:

class TestClass{
public:
TestClass(){}
private:
static const double h= 9.9 ;// c++11下报错;

//错误描述:
//error: 'constexpr' needed for in-class initialization of static data member
//'const double TestClass::h' of non-integral type [-fpermissive]

static constexpr float g = 9.5f; //不报错;
};


问题:
1. 为什么用constexpr 不报错,但是用const 就报错; 不是都说constexpr 的要求比const 更严格么?
2. 第一句报错的情况下,如果不采用c++11 ,而是用老版本的c++ 版本编译,倒是不报错,可以顺利通过;这又是为什么?

谢谢!
...全文
472 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
真相重于对错 2020-07-20
  • 打赏
  • 举报
回复
我这里无论vs2019,vs2010,vs2015,gcc 9.2.0都报错
真相重于对错 2020-07-20
  • 打赏
  • 举报
回复
这个不是什么可不苛刻,他们表示的不同语义。 不是什么松不松的关系。 而且static const double 在类内部定义,无论新的还是老的编译器都会出错。如果不出错说明那个编译器不符合c++的标准。也就是说那个只是编译器的扩展。而不能认为是C++的标准。 具体原因,前面我说了
levonsoft 2020-07-20
  • 打赏
  • 举报
回复
引用 4 楼 真相重于对错 的回复:
const constexpr 语义不一样,虽然都是只读,但是const 不保证一定在编译期内确定,而constexpr 则要求必须在编译期内确定
例如以下代码
const int fun(){
int b;
cin>>b;
return b;
}
const int x=fun(); //ok
constexpr int x=fun();//error;


这个理解,所以说constexpr 比const 要求更苛刻,,但现在是constexpr ok,要求更松的const 报错了。
levonsoft 2020-07-20
  • 打赏
  • 举报
回复
引用 5 楼 真相重于对错 的回复:
类大括号内相当于声明而非定义,static 类成员需要在外部定义。const static int 想当于字面量,可以在类内部初始化。
const static double 为何不行 是历史原因,因为c++ 11之前浮点没有标准。编译期的浮点数可能不同于运行期的浮点。所以C++11之前的编译器是不允许const static double ,现在的编译器沿袭这个规定。我不知道你的能编译过是什么编译器,反正我这里vs2010,vs2015都不可以。


=================

1. static 类成员需要在外部定义, 这是对的;一般也推荐这么做。我们只是做技术探讨,嘿;
2. 编译期的浮点数可能不同于运行期的浮点, 这个倒是有可能;
但现在是开启c++11 支持后,const double 报错,不开启反而是没报错; 所以有点奇怪;

3. 编译器版本是gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4
可能和vs还是有点差别;
levonsoft 2020-07-20
  • 打赏
  • 举报
回复
引用 11 楼 uouo88 的回复:
楼主你好,这个我觉得是个语法问题,你可以死记硬背好了,规则如下:

根据C++ primer第五版(英文版)原文摘取如下:
we can provide in-class initializers for static members that have const integral type and must do so for static members that are constexprs of literal type.

如上英文的大致意思:
我们可以为const静态数据成员提供整型的类内初始值。constexprs的静态数据成员必须提供类内初始值。

对于这句话的个人理解如下:
算术类型包括整型和浮点型。整型包括bool、char、int、short、long等。浮点型包括float和double等(详见C++Primer)。
const的静态数据成员(即static const的数据成员)可以使用整型类型类内初始值来初始化。
constexprs的静态成员(即static constexpr的数据成员)必须使用算术类型类内初始值来初始化(包含整形类型和浮点型类型)。

希望给你带来帮助,谢谢。


=======
谢谢你回复的这么详细哈。。
目前这样理解我觉得没问题。就当规定了
uouo88 2020-07-20
  • 打赏
  • 举报
回复
楼主你好,这个我觉得是个语法问题,你可以死记硬背好了,规则如下: 根据C++ primer第五版(英文版)原文摘取如下: we can provide in-class initializers for static members that have const integral type and must do so for static members that are constexprs of literal type. 如上英文的大致意思: 我们可以为const静态数据成员提供整型的类内初始值。constexprs的静态数据成员必须提供类内初始值。 对于这句话的个人理解如下: 算术类型包括整型和浮点型。整型包括bool、char、int、short、long等。浮点型包括float和double等(详见C++Primer)。 const的静态数据成员(即static const的数据成员)可以使用整型类型类内初始值来初始化。 constexprs的静态成员(即static constexpr的数据成员)必须使用算术类型类内初始值来初始化(包含整形类型和浮点型类型)。 希望给你带来帮助,谢谢。
上官永石 2022-02-23
  • 举报
回复
@uouo88 你好,看C++ primer第五版(中文版)时,发现了这个问题,你提供的英文片段,在中文版的翻译中是这样描述的:通常情况下,类内的静态成员不应该在类的内部初始化。然而,我们可以为静态成员提供 const 整数类型的类内初始值,不过要求静态成员必须是字面值常量类型的 constexpr 。 所以按照中文版的理解,应该是只有constexpr类型的字面值常量可以提供类内初始值,而 const 类型的字面值常量是不能类内初始化的。 但是在我进行实验时发现 static const int 的字面值是可以在类内初始化的,而 static const double 类型进行类内初始化时会报错,static constexpr double 类型的可以类内初始化。 通过网上的查阅,找到了这个资料 https://exp.newsmth.net/topic/article/8b99a992ebf87282be6fd8f94ce541c2, 下面回答是 static const int 是特殊情况。 我的环境是 vs2019,希望给大家一个参考,如有错误请指出,谢谢!
sdghchj 2020-07-18
  • 打赏
  • 举报
回复
有了static constexpr的存在就没有static const在类内初始化的必要,但考虑到作为数组的size,还是保留了static const 整型的类内初始化。
真相重于对错 2020-07-18
  • 打赏
  • 举报
回复
类大括号内相当于声明而非定义,static 类成员需要在外部定义。const static int 想当于字面量,可以在类内部初始化。 const static double 为何不行 是历史原因,因为c++ 11之前浮点没有标准。编译期的浮点数可能不同于运行期的浮点。所以C++11之前的编译器是不允许const static double ,现在的编译器沿袭这个规定。我不知道你的能编译过是什么编译器,反正我这里vs2010,vs2015都不可以。
真相重于对错 2020-07-18
  • 打赏
  • 举报
回复
const constexpr 语义不一样,虽然都是只读,但是const 不保证一定在编译期内确定,而constexpr 则要求必须在编译期内确定 例如以下代码 const int fun(){ int b; cin>>b; return b; } const int x=fun(); //ok constexpr int x=fun();//error;
  • 打赏
  • 举报
回复
这个是因为在定义类的时候直接赋值导致的。可以理解为历史原因。C
levonsoft 2020-07-17
  • 打赏
  • 举报
回复
错误描述我理解了,就是说静态成员变量如果在类内初始化;只能是const+整形;
这可以理解;
定义为int 确实就也没问题;

但问题是constexpr 为啥可以?老版本为啥可以?疑惑在这里。
一叶小舟_郭 2020-07-17
  • 打赏
  • 举报
回复
我没试你的代码,不过就你提供的错误信息,是不是你没看错误描述.

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧