简体   繁体   中英

How to use constant in class namespace as the array and template parameters?

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 :

  • at compile time, the compiler uses the value of A::someNumber any time it needs. And it notes that class A contains one static field named someNumber .
  • at link time, the linker ensure that there is only one instance of the 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM