为什么我不能在类中有一个非积分的静态const成员? [英] Why can't I have a non-integral static const member in a class?

查看:132
本文介绍了为什么我不能在类中有一个非积分的静态const成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到C ++不会编译以下内容:

I noticed C++ will not compile the following:

class No_Good {
  static double const d = 1.0;
};

但是,它会愉快地允许一个变体,其中double被更改为一个int,无符号,类型:

However it will happily allow a variation where the double is changed to an int, unsigned, or any integral type:

class Happy_Times {
  static unsigned const u = 1;
};

我的解决方案是将其改为:

My solution was to alter it to read:

class Now_Good {
  static double d() { return 1.0; }
};

,并指出编译器将足够聪明以在必要时内联...但它让我好奇。

and figure that the compiler will be smart enough to inline where necessary... but it left me curious.

为什么C ++设计器允许我静态const一个int或无符号,而不是一个双?

Why would the C++ designer(s) allow me to static const an int or unsigned, but not a double?

编辑:我在Windows XP上使用visual studio 7.1(.net 2003)。

I am using visual studio 7.1 (.net 2003) on Windows XP.

编辑2:

问题已得到解答,但是完成后,我看到的错误:

Question has been answered, but for completion, the error I was seeing:

error C2864: 'd' : only const static integral data members can be initialized inside a class or struct


推荐答案

问题是,对于整数,编译器通常不必为常量创建内存地址。它在运行时不存在,并且每次使用它都会内联到周围的代码中。它仍然可以决定给它一个内存位置 - 如果它的地址是永远采取(或如果它通过const引用一个函数),它必须。为了给它一个地址,它需要在一些翻译单元中定义。在这种情况下,您需要将声明与定义分开,否则将在多个翻译单元中定义。

The problem is that with an integer, the compiler usually doesn't have to ever create a memory address for the constant. It doesn't exist at runtime, and every use of it gets inlined into the surrounding code. It can still decide to give it a memory location - if its address is ever taken (or if it's passed by const reference to a function), that it must. In order to give it an address, it needs to be defined in some translation unit. And in that case, you need to separate the declaration from the definition, since otherwise it would get defined in multiple translation units.

使用g ++无优化( -O0 ),它会自动将常量整数变量,而不是常量双精度值。在更高的优化级别(例如 -O1 ),它将常数双精度。因此,以下代码在 -O1 下编译,但不在 -O0

Using g++ with no optimization (-O0), it automatically inlines constant integer variables but not constant double values. At higher optimization levels (e.g. -O1), it inlines constant doubles. Thus, the following code compiles at -O1 but NOT at -O0:

// File a.h
class X
{
 public:
  static const double d = 1.0;
};

void foo(void);

// File a.cc
#include <stdio.h>

#include "a.h"

int main(void)
{
  foo();
  printf("%g\n", X::d);

  return 0;
}

// File b.cc
#include <stdio.h>

#include "a.h"

void foo(void)
{
  printf("foo: %g\n", X::d);
}

命令行:

g++ a.cc b.cc -O0 -o a   # Linker error: ld: undefined symbols: X::d
g++ a.cc b.cc -O1 -o a   # Succeeds

对于最大可移植性,您应该在头文件中声明常量,文件。没有优化,这不会损害性能,因为你不是优化,但启用优化,这可能会损害性能,因为编译器不能再将这些常量内联到其他源文件,除非启用整个程序优化 。

For maximal portability, you should declare your constants in header files and define them once in some source file. With no optimization, this will not hurt performance, since you're not optimizing anyways, but with optimizations enabled, this can hurt performance, since the compiler can no longer inline those constants into other source files, unless you enable "whole program optimization".

这篇关于为什么我不能在类中有一个非积分的静态const成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆