2015-01-16 56 views
5

我有一些常量,只需要在编译时使用,以简化代码,所以我不需要在运行时可用的实际变量。如何在C++类中定义编译时(静态)常量?

传统上这样做的方式是#define NAME 123,但我想要一个类型安全的替代方案。

以外的类可以const int name = 123;哪些工作正常,但似乎不可能把它放在课堂上。例如这样的:

class Example { 
    public: 
     const double usPerSec = 1000000.0; 
}; 
double usOneMinute = 60 * Tempo::usPerSec; 

工程用Visual C++,但不与海湾合作委员会的工作:

error: non-static const member ‘const double Example::usPerSec’, 
    can’t use default assignment operator 

您可以通过它的静态修复它,但随后的Visual C++抱怨:

error C2864: 'Example::usPerSec' : a static data member with an in-class 
    initializer must have non-volatile const integral type 
    type is 'const double' 

我猜这意味着VC++将只接受static const int

我想避免在构造函数中设置值,因为然后我需要在运行时访问该值的类的实例,而实际上我希望它在编译时处理,就像#define一样。

那么如何在一个类中定义一个常量为double,而不诉诸于全局或使用#define,这将在没有该类的实例的情况下工作,并且可以与主要的C++ 03编译器一起工作?

回答

10

的任何实例有积分和其他类型之间这里的差异。对于整型你总是可以将它们定义为const static成员在

struct Example 
{ 
    const static int name = 123; // added 'static' to code in text of question 
    const static unsigned usPerSec = 1000000; 
}; 

对于非整数类型,在你的例子,如double,情况就比较复杂了。自2011年(使用大多数编译器编译器选项std=c++11),你可以简单地这样做:

struct Example 
{ 
    constexpr static double usPerSec = 1000000.0; 
}; 

但用gcc,这

struct Example 
{ 
    const static double usPerSec = 1000000.0; 
}; 

也应该工作在C++ 03(这是一个GNU扩展)。

然而,在C++ 03的标准方法,其中也使用标准库本身(例如在std::numeric_limits<>),是一个static成员函数

struct Example 
{ 
    static double usPerSec() { return 1000000.0; } 
}; 
+1

'+ 1'提到'std :: numeric_limits <>',我觉得这很有用。 – Angew

1

此代码工作在两个VC++和GCC:

class Example { 
public: 
    static const double usPerSec ; 
}; 
const double Example::usPerSec=10000.0; 
double usOneMinute = 60 * Example::usPerSec; 
4

我看到C++ 03两种可能的方法:

  1. 使用静态成员函数,依靠内联:

    class Example { 
        public: 
         static double usPerSec() { return 1000000.0; } 
    }; 
    double usOneMinute = 60 * Example::usPerSec(); 
    
  2. 使用静态数据成员并在常量折叠上退出(使用常量的值将是comp贡献在运行时):

    class Example { 
        public: 
         static const double usPerSec; 
    }; 
    double usOneMinute = 60 * Example::usPerSec; 
    
    // Somewhere in one .cpp 
    const double Example::usPerSec = 1000000.0; 
    
+0

如果您在库中使用它并使用MSVC++进行编译,第二个选项会提供未解析的外部。不得不在DLL中导出符号对于一个在库之外通常不会显示的编译时常量而言肯定是矫枉过正的! – Malvineous

1

你必须让它静态常量,然后给它的价值之外类。不要在构造函数中做。您不必制作实例

class Example { 
public: 
    static const double usPerSec; 

};现在

double Example::usPerSec = 1000000.0; 

,你可以在任何地方使用它,而使得类

double someVar = Example::usPerSec; 
2

如果我是你,我会放它在一个命名空间中:

namespace MyExampleNamespace { 
    const double usPerSec = 1000000.0; 
} 
double usOneMinute = 60 * MyExampleNamespace::usPerSec;