declare a array of const ints in C++ - c++

I have a class and I want to have some bit masks with values 0,1,3,7,15,...
So essentially i want to declare an array of constant int's such as:
class A{
const int masks[] = {0,1,3,5,7,....}
}
but the compiler will always complain.
I tried:
static const int masks[] = {0,1...}
static const int masks[9]; // then initializing inside the constructor
Any idea on how this can be done?
Thanks!

class A {
static const int masks[];
};
const int A::masks[] = { 1, 2, 3, 4, ... };
You may want to fixate the array within the class definition already, but you don't have to. The array will have a complete type at the point of definition (which is to keep within the .cpp file, not in the header) where it can deduce the size from the initializer.

// in the .h file
class A {
static int const masks[];
};
// in the .cpp file
int const A::masks[] = {0,1,3,5,7};

enum Masks {A=0,B=1,c=3,d=5,e=7};

you can initialize variables only in the constructor or other methods.
'static' variables must be initialized out of the class definition.
You can do this:
class A {
static const int masks[];
};
const int A::masks[] = { 1, 2, 3, 4, .... };

Well, This is because you can't initialize a private member without calling a method.
I always use Member Initialization Lists to do so for const and static data members.
If you don't know what Member Initializer Lists are ,They are just what you want.
Look at this code:
class foo
{
int const b[2];
int a;
foo(): b{2,3}, a(5) //initializes Data Member
{
//Other Code
}
}
Also GCC has this cool extension:
const int a[] = { [0] = 1, [5] = 5 }; // initializes element 0 to 1, and element 5 to 5. Every other elements to 0.

Related

How to initialize static std::array with static const variable?

How to initialize static std:array that uses static const variable as size? I tried searching for similar questions but std::array is relatively new so theres not much to be found.
// ExampleClass.h
class ExampleClass {
public:
static const size_t NUMBER_OF_INDEXES = 5;
private:
static std::array<int, NUMBER_OF_INDEXES> myArray;
};
Like any other static data member, ExampleClass::myArray should have an out-of-line definition in exactly one translation unit, where you write down its type and its qualified name as usual:
std::array<int, ExampleClass::NUMBER_OF_INDEXES> ExampleClass::myArray = {1, 2, 3, 4, 5};

Array of floats throws "incomplete type is not allowed"

I'm still fairly new to C++, so maybe its a very simple error I made here.
I wanted to initialize a private float array in one of my classes, like this.
float firstVect[] = {0.0f,0.0f,0.0f};
but firstVect is underlined with the explanation of incomplete type.
On the other hand two lines below the float array i have an int array looking like this:
int normalNumberOfDigits[]= {0,0,0};
The compile does not complain about the int array but only about the float array. Why?
Full code of my class:
class DataFilter
{
public:
int filterMovement(float vect3[3])
{
//TBD
}
private:
float firstVect[] = {0.0f,0.0f,0.0f};
int initialized = 0;
int normalNumberOfDigits[]= {0,0,0};
int determinNumberOfDigits(float testValue)
{
//TBD
}
};
Compiling with a modern version of clang++ makes your mistake obvious:
error: array bound cannot be deduced from an in-class initializer
You need to explicitly specify the size of the arrays (if you want to use a C-style array) in your class initialization:
class DataFilter
{
// ...
float firstVect[3] = {0.0f,0.0f,0.0f};
int initialized = 0;
int normalNumberOfDigits[3]= {0,0,0};
// ...
};
"The compile does not complain about the int array but only about the float array. Why?"
Compiling with a modern version of g++ makes this obvious as well:
error: flexible array member DataFilter::normalNumberOfDigits not at end of class DataFilter
When you declare an array without an explicit size, the compiler thinks that it is a flexible array, which is a C-only feature. It seems to be allowed in C++ as a non-standard g++ extension.
Non-static data members must have complete type, i.e. if they are arrays they must contain the array size. The size cannot be inferred from any initializers, because initializers are a) optional and b) not really part of the class definition, but rather implicitly part of all constructor function definitions.
Simple fix:
float firstVect[3] = {0.0f,0.0f,0.0f};
// ^^^
To clarify the explanation a bit: A class definition with default member initializer like this:
struct Foo
{
int a[3] = {1, 2, 3};
};
is conceptually the same as:
struct Foo
{
Foo();
int a[3];
};
Foo::Foo() : a{1, 2, 3} {}
You see now that the initializer is not really a part of the class definition, and thus cannot be used to deduce the array size.
A more extreme example is this:
struct Bar
{
Bar(int) : a{1, 2, 3} {}
Bar(float): a{1, 1} {}
Bar() = default;
int a[???] = {4, 4, 4, 4, 4};
};
What should the type of Bar::a be here?
Clang reports a clearer error:
fatal error: array bound cannot be deduced from an in-class initializer
You have to explicitly size your arrays:
class DataFilter
{
// ...
private:
float firstVect[3] = {0.0f,0.0f,0.0f};
int normalNumberOfDigits[3]= {0,0,0};
};

Set Array to an Initialized, Passed-In Array in C++

Pardon the extraordinarily basic question, but as a Java programmer this C++ error is not exactly "clicking", so to speak.
I want to create and initialize an array in one function, then pass that array to another function. Within the receiving function, I'd like to access elements of the passed-in array.
As an (abbreviated) example:
class demo{
main() {
int members[] = { 1, 2, 3, 4, 5 };
example.function(members);
}
}
Which would pass array members to the following function:
class example {
int members[];
void function(int mem[]) {
members = mem;
}
}
Which gives me the error:
error: incompatible types in assignment of ‘int*’ to ‘int [0]’
I want example.members[] to equal demo.members[]. I understand why I'm getting an int* in example.function, but can't figure out how to set up the array in class example.
Just do it the C++ way, and use std::vector:
#include <vector>
class example {
std::vector<int> members;
void function(std::vector<int> const& mem) {
members = mem;
}
};
In C++11 you could avoid the copy when an rvalue is provided (such as in: ex.function({1, 2, 3})) by letting function() take its argument by value and then move it into the data member:
#include <vector>
class example {
std::vector<int> members;
void function(std::vector<int> mem) {
members = std::move(mem);
}
};
Change the private member variable example::members to type int *.
class Example {
int *members;
void function(int *mem) {
members = mem;
}
}
void main () {
int array[] = { 1, 2, 3, 4, 5 };
Example ex;
ex.function(array);
}
You can not directly assign regular array, if you really want to use regular array, you need to do it in a loop.
Try to use std::vector or std::array ( std::array documentation) instead.
For example: std::vector way:
class example {
std::vector<int> members;
void function(const std::vector<int>& mem) {
members = mem;
}
}

initialise const array inside class

In Visual C++, how can I initialise a constant array inside of a class?
This is an example of how to do it outside of a class:
const char k_colors[] =
{
'R',
'G',
'B',
};
Now how do I need to change that? (I tried putting static in front of it, which didn't work)
Edit: You're right, I should just use single characters.
If you want it to be static, you'll need to initialize it outside the class:
class foo
{
public:
static const char k_colors[3];
foo() { }
};
const char foo::k_colors[] = {'a', 'b', 'c'};
Also, you probably want it to be a const char *[] since it looks like you're trying to initialize strings, so it'd be:
const char *foo::k_colors[] = {"Red", "Green", "Blue"};
I tried putting static in front of it, which didn't work
You can't initialise the static member array (or any member array) inside the class definition. Do it outside of the class definition:
class X
{
static const char* k_colors[3];
};
const char* X::k_colors[] = { "Red", "Green", "Blue" };
In C++11 you can use the constructor initializer list as mentioned
class A {
const int arr[2];
// constructor
A()
: arr ({1, 2})
{ }
};
Or you can use static const array
In header file:
class A {
static const int a[2];
// other bits follow
};
In source file (or in separate place from the declaration above)
const int A::a[] = { 1, 2 };
Of course you can always use std::vector<int> and for loop as well.
I think you can initialize through the constructor initializer list
Refer here
Also the char should be char*
Extract from the above link:
prior to C++11 you need to do just this to default-initialise each element of the array:
: k_colors()
With C++11 it is more recommended use uniform initialisation syntax:
: k_colors{ }
And that way you can actually put things into the array which you couldn't before:
: k_colors{"red","green"}

How do you declare arrays in a c++ header?

This is related to some other questions, such as: this, and some of my other questions.
In this question, and others, we see we can declare and initialise string arrays in one nice step, for example:
const char* const list[] = {"zip", "zam", "bam"}; //from other question
This can be done in the implementation of a function with no bother, or in the body of a .cpp file, outside any scope.
What I want to do is to have an array like this as as member of a class I am using, something like this:
class DataProvider : public SomethingElse
{
const char* const mStringData[] = {"Name1", "Name2", "Name3", ... "NameX"};
public:
DataProvider();
~DataProvider();
char* GetData()
{
int index = GetCurrentIndex(); //work out the index based on some other data
return mStringData[index]; //error checking and what have you omitted
}
};
But, the compiler complains and I can't seem to work out why. Is it possible to declare and initialise an array like this in one step in a class definition? Are there alternatives that are better?
Use the keyword static and external initialization to make the array a static member of the class:
In the header file:
class DataProvider : public SomethingElse
{
static const char* const mStringData[];
public:
DataProvider();
~DataProvider();
const char* const GetData()
{
int index = GetCurrentIndex(); //work out the index based on some other data
return mStringData[index]; //error checking and what have you omitted
}
};
In the .cpp file:
const char* const DataProvider::mStringData[] = {"Name1", "Name2", "Name3", ... "NameX"};
The reason you can't declare your array like that (const char* []) is that:
you can't have initializers in the class declaration, and so
the syntax const char* [] does not state how much space the compiler needs to allocate for each instance (your array is declared as instance variable).
Besides, you probably want to make that array static, since it is in essence a constant value.
This is not possible in C++. You cannot directly initialize the array. Instead you have to give it the size it will have (4 in your case), and you have to initialize the array in the constructor of DataProvider:
class DataProvider {
enum { SIZEOF_VALUES = 4 };
const char * values[SIZEOF_VALUES];
public:
DataProvider() {
const char * const v[SIZEOF_VALUES] = {
"one", "two", "three", "four"
};
std::copy(v, v + SIZEOF_VALUES, values);
}
};
Note that you have to give up on the const-ness of the pointers in the array, since you cannot directly initialize the array. But you need to later set the pointers to the right values, and thus the pointers need to be modifiable.
If your values in the array are const nevertheless, the only way is to use a static array:
/* in the header file */
class DataProvider {
enum { SIZEOF_VALUES = 4 };
static const char * const values[SIZEOF_VALUES];
};
/* in cpp file: */
const char * const DataProvider::values[SIZEOF_VALUES] =
{ "one", "two", "three", "four" };
Having the static array means all objects will share that array. Thus you will have saved memory too.