Is there any reason why codeblocks is telling me that I can't make an array? I'm simply trying to do:
const unsigned int ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};
and it's giving me
error: a brace-enclosed initializer is not allowed here before '{' token
I have changed other parts of the initializer, but the error is always saying the same thing. This doesn't seem to make sense, since this is one of the first things I learned in c++.
You say that you did this within a class, as a private variable.
Recall that (at the moment), member variables may not be initialised in the same place where you declare them (with a few exceptions).
struct T {
std::string str = "lol";
};
is not ok. It has to be:
struct T {
std::string str;
T() : str("lol") {}
};
But, to add insult to injury, pre-C++0x you cannot initialise arrays in the ctor-initializer!:
struct T {
const unsigned int array[10];
T() : array({0,1,2,3,4,5,6,7,8,9}) {} // not possible :(
};
And, because your array's elements are const, you can't rely on assignment either:
struct T {
const unsigned int array[10];
T() {
for (int i = 0; i < 10; i++)
array[i] = i; // not possible :(
}
};
However, as some other contributors have quite rightly pointed out, there seems little point in having a copy of the array for each instance of T if you can't modify its elements. Instead, you could use a static member.
So, the following will ultimately solve your problem in what's — probably — the best way:
struct T {
static const unsigned int array[10];
};
const unsigned int T::array[10] = {0,1,2,3,4,5,6,7,8,9};
Hope this helps.
Since this is a private member variable in a class (according to the comment), this is indeed not allowed in C++03.
C++0x, partially supported by many modern compilers, allows the following to compile:
class C
{
const unsigned int ARRAY[10];
public:
C() : ARRAY{0,1,2,3,4,5,6,7,8,9} {}
};
int main()
{
C obj; // contains a non-static const member: non-assignable
}
However, non-static const members only make sense if they contain different values in different instances of the class. If every instance is to contain the same {0,1,2,3,4,5,6,7,8,9}, then you should make it static, which also makes it possible to do this in C++98:
class C
{
static const unsigned int ARRAY[10];
public:
C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};
int main()
{
C obj;
}
Related
#include <iostream>
using namespace std;
class T1
{
const int t = 100;
public:
T1()
{
cout << "T1 constructor: " << t << endl;
}
};
When I am trying to initialize the const member variable t with 100. But it's giving me the following error:
test.cpp:21: error: ISO C++ forbids initialization of member ‘t’
test.cpp:21: error: making ‘t’ static
How can I initialize a const value?
The const variable specifies whether a variable is modifiable or not. The constant value assigned will be used each time the variable is referenced. The value assigned cannot be modified during program execution.
Bjarne Stroustrup's explanation sums it up briefly:
A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.
A const variable has to be declared within the class, but it cannot be defined in it. We need to define the const variable outside the class.
T1() : t( 100 ){}
Here the assignment t = 100 happens in initializer list, much before the class initilization occurs.
Well, you could make it static:
static const int t = 100;
or you could use a member initializer:
T1() : t(100)
{
// Other constructor stuff here
}
There are couple of ways to initialize the const members inside the class..
Definition of const member in general, needs initialization of the variable too..
1) Inside the class , if you want to initialize the const the syntax is like this
static const int a = 10; //at declaration
2) Second way can be
class A
{
static const int a; //declaration
};
const int A::a = 10; //defining the static member outside the class
3) Well if you don't want to initialize at declaration, then the other way is to through constructor, the variable needs to be initialized in the initialization list(not in the body of the constructor). It has to be like this
class A
{
const int b;
A(int c) : b(c) {} //const member initialized in initialization list
};
If you don't want to make the const data member in class static, You can initialize the const data member using the constructor of the class.
For example:
class Example{
const int x;
public:
Example(int n);
};
Example::Example(int n):x(n){
}
if there are multiple const data members in class you can use the following syntax to initialize the members:
Example::Example(int n, int z):x(n),someOtherConstVariable(z){}
You can upgrade your compiler to support C++11 and your code would work perfectly.
Use initialization list in constructor.
T1() : t( 100 )
{
}
Another solution is
class T1
{
enum
{
t = 100
};
public:
T1();
};
So t is initialised to 100 and it cannot be changed and it is private.
If a member is a Array it will be a little bit complex than the normal is:
class C
{
static const int ARRAY[10];
public:
C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};
or
int* a = new int[N];
// fill a
class C {
const std::vector<int> v;
public:
C():v(a, a+N) {}
};
Another possible way are namespaces:
#include <iostream>
namespace mySpace {
static const int T = 100;
}
using namespace std;
class T1
{
public:
T1()
{
cout << "T1 constructor: " << mySpace::T << endl;
}
};
The disadvantage is that other classes can also use the constants if they include the header file.
This is the right way to do. You can try this code.
#include <iostream>
using namespace std;
class T1 {
const int t;
public:
T1():t(100) {
cout << "T1 constructor: " << t << endl;
}
};
int main() {
T1 obj;
return 0;
}
if you are using C++10 Compiler or below then you can not initialize the cons member at the time of declaration. So here it is must to make constructor to initialise the const data member. It is also must to use initialiser list T1():t(100) to get memory at instant.
you can add static to make possible the initialization of this class member variable.
static const int i = 100;
However, this is not always a good practice to use inside class declaration, because all objects instacied from that class will shares the same static variable which is stored in internal memory outside of the scope memory of instantiated objects.
In C++ you cannot initialize any variables directly while the declaration.
For this we've to use the concept of constructors.
See this example:-
#include <iostream>
using namespace std;
class A
{
public:
const int x;
A():x(0) //initializing the value of x to 0
{
//constructor
}
};
int main()
{
A a; //creating object
cout << "Value of x:- " <<a.x<<endl;
return 0;
}
Hope it would help you!
In the old days structure like that:
typedef struct A {
int m_i;
int m_j;
} A;
Allocated on the heap or declared locally in a function without being memset would have its members uninitialized.
However, to my utter surprise this little program shows it is always set to 0.
#include <stdio.h>
typedef struct A {
int m_i;
int m_j;
} A;
void f(const A& a) {
printf("i=%i, j=%i\n", a.m_i, a.m_j);
}
void y() {
f({10});
}
int main() {
y();
return 0;
}
Built using g++ -std=c++11 a.cpp
I would just in case defined a constructor to make sure they are zero, but my various tests show (using code found on the internet) that I don't have to.
Is this a shear coincidence or extended initializer list is a guarantor of having memory being memset?
typedef struct A {
int m_i;
int m_j;
} A;
is an aggregate. When you initialize an aggregate with a braced-init-list it uses each element in the list to initialize each member of the aggregate. If you don't provide enough elements in the braced-init-list then each subsequent member is guaranteed to be value initialized, which for fundamental types means they are zero initialized..
#include <iostream>
using namespace std;
class T1
{
const int t = 100;
public:
T1()
{
cout << "T1 constructor: " << t << endl;
}
};
When I am trying to initialize the const member variable t with 100. But it's giving me the following error:
test.cpp:21: error: ISO C++ forbids initialization of member ‘t’
test.cpp:21: error: making ‘t’ static
How can I initialize a const value?
The const variable specifies whether a variable is modifiable or not. The constant value assigned will be used each time the variable is referenced. The value assigned cannot be modified during program execution.
Bjarne Stroustrup's explanation sums it up briefly:
A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.
A const variable has to be declared within the class, but it cannot be defined in it. We need to define the const variable outside the class.
T1() : t( 100 ){}
Here the assignment t = 100 happens in initializer list, much before the class initilization occurs.
Well, you could make it static:
static const int t = 100;
or you could use a member initializer:
T1() : t(100)
{
// Other constructor stuff here
}
There are couple of ways to initialize the const members inside the class..
Definition of const member in general, needs initialization of the variable too..
1) Inside the class , if you want to initialize the const the syntax is like this
static const int a = 10; //at declaration
2) Second way can be
class A
{
static const int a; //declaration
};
const int A::a = 10; //defining the static member outside the class
3) Well if you don't want to initialize at declaration, then the other way is to through constructor, the variable needs to be initialized in the initialization list(not in the body of the constructor). It has to be like this
class A
{
const int b;
A(int c) : b(c) {} //const member initialized in initialization list
};
If you don't want to make the const data member in class static, You can initialize the const data member using the constructor of the class.
For example:
class Example{
const int x;
public:
Example(int n);
};
Example::Example(int n):x(n){
}
if there are multiple const data members in class you can use the following syntax to initialize the members:
Example::Example(int n, int z):x(n),someOtherConstVariable(z){}
You can upgrade your compiler to support C++11 and your code would work perfectly.
Use initialization list in constructor.
T1() : t( 100 )
{
}
Another solution is
class T1
{
enum
{
t = 100
};
public:
T1();
};
So t is initialised to 100 and it cannot be changed and it is private.
If a member is a Array it will be a little bit complex than the normal is:
class C
{
static const int ARRAY[10];
public:
C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};
or
int* a = new int[N];
// fill a
class C {
const std::vector<int> v;
public:
C():v(a, a+N) {}
};
Another possible way are namespaces:
#include <iostream>
namespace mySpace {
static const int T = 100;
}
using namespace std;
class T1
{
public:
T1()
{
cout << "T1 constructor: " << mySpace::T << endl;
}
};
The disadvantage is that other classes can also use the constants if they include the header file.
This is the right way to do. You can try this code.
#include <iostream>
using namespace std;
class T1 {
const int t;
public:
T1():t(100) {
cout << "T1 constructor: " << t << endl;
}
};
int main() {
T1 obj;
return 0;
}
if you are using C++10 Compiler or below then you can not initialize the cons member at the time of declaration. So here it is must to make constructor to initialise the const data member. It is also must to use initialiser list T1():t(100) to get memory at instant.
you can add static to make possible the initialization of this class member variable.
static const int i = 100;
However, this is not always a good practice to use inside class declaration, because all objects instacied from that class will shares the same static variable which is stored in internal memory outside of the scope memory of instantiated objects.
In C++ you cannot initialize any variables directly while the declaration.
For this we've to use the concept of constructors.
See this example:-
#include <iostream>
using namespace std;
class A
{
public:
const int x;
A():x(0) //initializing the value of x to 0
{
//constructor
}
};
int main()
{
A a; //creating object
cout << "Value of x:- " <<a.x<<endl;
return 0;
}
Hope it would help you!
Using an 03 standard-compliant compiler (safety-critical variant of gcc-3.3.2).
The standard says that static member objects must be defined (9.4.2 (4)). It also states that the one-definition rule holds, but no diagnostic is required (9.4.2 (5)). Is the following code valid?
struct fred
{
static const int JOE=1;
int m_joe;
fred() : m_joe(JOE) {}
};
That is, there is no "static const int fred::JOE;".
I ask because we have a case (apparently) where a static const int in a template class was never defined, and the code worked in some contexts, but not others. I replaced the static const int with an enum, and it worked in all cases.
Were we definitely in the Land of Undefined Behavior?
A static const int defines a compile-time constant; I'm afraid I can't refer to a specific part of the standard. The only time you need a definition for it is if you try to take the address of it or create a reference. If you use an enum instead, the compiler will create a temporary variable for you when you need a reference.
struct test
{
static const int one = 1;
enum { two = 2 };
};
void printint(const int & i)
{
cout << i << endl;
}
int main() {
printint(test::one); // error
printint(test::two); // no error
return 0;
}
How should I write a constructor for a class to initialize a member that is a const structure / has const fields?
In the following example, I define a constructor within structure B and it works fine to initialize it's const fields.
But when I try to use the same technique to initialize const fields of structure C within class A it doesn't work. Can someone please help me and rewrite my class A in a way, that it starts working?
#include <iostream>
class A
{
public:
struct C
{
C (const int _x) : x (_x) {}
const int x;
};
C c (3);
};
int main (int argc, char *argv[])
{
struct B
{
B (const int _x) : x (_x) {}
const int x;
};
B b (2);
std::cout << b.x << std::endl;
A a;
std::cout << a.c.x << std::endl;
return 0;
}
P.S.
I did some search and I think, I understand, that unless I have C++11 support or want to use boost library, I have to define a helper function to initialize a const struct within initialization list
(C++ Constant structure member initialization)
but it seems to be crazy that I have to define alike struct, but with non const fields to initialize a struct with const fields, doesn't it?
Another thing that I found tells that I should initialize const members in a constructor of the class A, rather than in a constructor of the struct C (C++ compile time error: expected identifier before numeric constant) but it also seems crazy to me, because why should I rewrite a class constructor every time I want to add a new struct, isn't it more convenient to have a separate constructor for each struct C within the class A?
I would be grateful to any comments that could possibly clarify my confusion.
I'd do the job like this:
#include <iostream>
class A {
public:
struct C {
C(const int _x) : x(_x) {}
const int x;
};
C c; // (3);
A() : c(3) {}
};
int main(int argc, char *argv []) {
A a;
std::cout << a.c.x << std::endl;
return 0;
}
Note that it's not a matter of using a ctor in A or in C, but of the ctor for A telling how the ctor for C should be invoked. If the value that will be passed will always be 3 that's not necessary, but I'm assuming you want to be a able to pass a value of your choice when you create the C object, and it will remain constant after that.
If the value will always be the same (3 in this case) you can simplify things a lot by also making the constant static:
struct A {
struct C {
static const int x = 3;
};
C c;
};
int main() {
A a;
std::cout << a.c.x << "\n";
}
So, if the value is identical for all instances of that class, make it static const, initialize it in place, and life is good. If the value is not known until you create an instance of the object, and remains constant thereafter for the life of that object, you need to pass it in through the constructors.
For a slightly different case, there's a third possibility: if C is an independent class (not nested inside of A) you might have a situation where other instances of C use various values, but all instances of C inside an A always use the same value. In this case, you'd do something like:
struct C {
const int x;
C(int x) : x(x) {}
};
struct A {
C c;
A() : c(3) {}
};
Of course, you can do the same thing when C is nested inside of A, but when/if you do, it generally means you're setting the same value for all instances of C, so you might as well use the static const approach instead. The obvious exception would be if A had multiple constructors, so (for example) A's default constructor passed one value for C::x and its copy constructor passed a different value.