I want to use the constant in class namespace as the size of a static array and the template parameter in another class. I have follow errors
// MS VS 2010 C++98
// A.h
class A
{
public:
const static int someNumber;
};
// A.cpp
#include <A.h>
const int A::someNumber = 5;
// B.h
#include <A.h>
class B
{
std::bitset<A::someNumber> btst; // Error! C2975: '_Bits' : invalid template argument
double control[A::someNumber]; // Error! C2466: cannot allocate an array of constant size 0
};
How can I avoid them?
In C++98, you can't use constexpr
as that wasn't introduced until C++11.
double control[A::someNumber]
needs to be compile-time evaluable and your definition of A::someNumber
resides in a different translation unit. That is what your compiler is complaining about.
However you can use an enum
. I'm borrowing this technique from idioms used in template metaprogramming:
class A
{
public:
enum {someNumber = 5};
}; /*and note this semicolon*/
Your problem is not that simple, because if you put all you declaration in one single file, it will compile and run correctly.
But just look at what compiler can see when it compiles Bh (assuming it is included in a main.cpp or B.cpp) :
#include "Ah"
: ok it contains const static int someNumber;
someNumber is a const int and its value will be given at link time
std::bitset<A::someNumber> btst
: ok a bitset, the size is A::someNumber
which is declared to be a const int, fine until here ... but wow, the value of the const is not known to the compiler at that time ! Let's assume it is 0 => and you get both errors because compiler has no way to know the future value of A::someNumber
!
Now we know that, the fix is simple : just write in Ah :
const static int someNumber = 5; // valid for a litteral const
Because now the compiler knows the value of A::someNumber
at compile time and can correctly compile a file including Bh
EDIT
You might be frightened at the idea of writing const static int someNumber = 5;
in Ah
because it could be included in many compilation units and you do not want to define same constant in many units. But in fact it is not a problem :
A::someNumber
any time it needs. And it notes that class A contains one static field named someNumber
. A::someNumber
. You can control that by printing the address of the static const field from different compilation units and you will get same value ... unless your developpement tools are seriously broken !
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.