Reputation: 1107
I have just found out that the following is not valid.
//Header File
class test
{
const static char array[] = { '1', '2', '3' };
};
Where is the best place to initialize this?
Upvotes: 52
Views: 105497
Reputation: 382860
With constexpr
you must define the value on the header even in C++11
If you use constexpr
instead of const
, then this answer suggests that you not only can, but must, define on header even in C++11:
#include <cassert>
struct MyClass {
static constexpr int is[] = {1, 2, 3};
static constexpr int i = 1;
};
// TODO is this ever mandatory? Create example that fails on -std=c++11.
// Pretty sure never mandatory in C++17 https://stackoverflow.com/a/40959093/895245
// constexpr int MyClass::is[];
int main (void) {
assert(MyClass::is[0] == 1);
assert(&MyClass::is[0] == &MyClass::is[1] - 1);
assert(MyClass::i == 1);
assert(&MyClass::i == &MyClass::i);
}
Compile and run with:
g++-10 -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
If instead you try:
struct MyClass {
static constexpr int is[];
};
constexpr int MyClass::is[] = {1, 2, 3};
compilation fails with:
main.cpp:4:26: error: ‘constexpr’ static data member ‘is’ must have an initializer
Tested on Ubuntu 20.04.
Upvotes: 2
Reputation: 15380
This is kind of an abuse of the system, but if you REALLY want to define it in the header file (and you don't have C++17), you can do this. It won't be a static member, but it will be a constant that only takes up storage per compilation unit (rather than per class instance):
(Put all of this code in the header file.)
namespace {
const char test_init_array[] = {'1', '2', '3'};
}
class test {
public:
const char * const array;
test() : array(test_init_array) {}
};
Upvotes: 0
Reputation: 663
You can always do the following:
class test {
static const char array(int index) {
static const char a[] = {'1','2','3'};
return a[index];
}
};
A couple nice things about this paradigm:
Upvotes: 39
Reputation: 2998
Now, in C++17, you can use inline variable
A simple static data member(N4424):
struct WithStaticDataMember { // This is a definition, no outofline definition is required. static inline constexpr const char *kFoo = "foo bar"; };
In your example:
//Header File
class test
{
inline constexpr static char array[] = { '1', '2', '3' };
};
should just work
Upvotes: 14
Reputation: 254461
The best place would be in a source file
// Header file
class test
{
const static char array[];
};
// Source file
const char test::array[] = {'1','2','3'};
You can initialize integer types in the class declaration like you tried to do; all other types have to be initialized outside the class declaration, and only once.
Upvotes: 58
Reputation: 41106
//Header File
class test
{
const static char array[];
};
// .cpp
const char test::array[] = { '1', '2', '3' };
Upvotes: 21