Re: static constants in a class
On 15/09/2011 00:06, Leigh Johnston wrote:
On 14/09/2011 22:43, Urs Thuermann wrote:
How should one define a constant, say of type int, in a class? The
only way that worked for me in all cases is to delcare the constant in
the class in the header file and define its value in the
implementation file:
---- foo.hh ----
class Foo {
public:
static const int N;
...
};
---- foo.cc ----
#include "foo.hh"
const int Foo::N = 10;
----------------
But this will prevent many optimizations by the compiler, e.g. when I
compile
---- bar.cc ----
void f() {
int array[N];
for (int i = 0; i< N; i++) { ... }
----------------
since the compiler doesn't know the value of N. Is it possible to
have the constant in foo.hh, i.e. visible in all translation units
including foo.hh, without getting other problems?
I tried two other ways, both having problems:
1. class Foo {
public:
static const int N;
...
};
const int Foo::N = 10;
If I include this into multiple translation units I get multiple
definitions of N and therefore a linker error.
2. class Foo {
public:
static const int N = 10;
...
};
This seemed to work at first glance, since the compiler will
optimize most accesses to N away and use the value directly.
But when N is used where a reference is needed, e.g.
some_std_list.push_back(N);
my compiler (gcc) produces an access to N which however is not
defined anywhere so I get a linker error again.
The traditional C way would be to use #define, but I wanted to avoid
that. Is there way to have the constant definition in the header
file?
Yes by using the template trick:
// constants.h
template <typename T>
struct my_constants_def
{
static const int N;
};
template <>
const int my_constants_def<void>::N = 42;
typedef my_constants_def<void> my_constants;
// main.cpp
int main(int argc, char* argv[])
{
std::vector<int> v;
v.push_back(my_constants::N);
std::cout << v[0];
}
Sorry I incorrectly specialized that template; I should have said:
template <typename T>
struct my_constants_def
{
static const int N;
};
template <typename T>
const int my_constants_def<T>::N = 42;
typedef my_constants_def<void> my_constants;
/Leigh