C++ Initialize a non-static array of pointers in constructor - c++

I want to initialize an array of pointers the nice way.. Something like
handler[numberOfIndexes] = {&bla, &ble, &bli, &blo , &blu};
But it doens't work this way. I get an error, obviously, because I'm trying to place an array of pointers to functions, in a single pointer to function:
cannot convert ‘<brace-enclosed initializer list>’ to ‘void (A::*)()’ in assignment
So, here's the code for you to test:
#include <iostream>
#include <list>
using namespace std;
class A
{
private:
void first();
void second();
void third ();
// and so on
void(A::*handlers[4])(void);
public:
A();
};
void A::first()
{
}
void A::second()
{
}
void A::third()
{
}
A::A()
{
//this is ugly
handlers[0] = &A::first;
handlers[1] = &A::second;
handlers[2] = &A::third;
//this would be nice
handlers[4] = {&A::first,&A::second,&A::third,0};//in static this would work, because it would be like redeclaration, with the type speficier behind
}
int main()
{
A sup;
return 0;
}
UPDATE:
In Qt this doesn't work.
I get :
syntax error: missing ';' before '}'
And if I change to
A::A() : handlers ({&A::first, &A::second, &A::third, 0})//notice the parentheses
then a this happens
Syntax Error: missing ')' before '{'
Warning: The elements of the array "A :: Handlers" are by default "initialized.
So, what's the problem with Qt?
By this point, you should have understood what I want to do. Just do a nice initialization of the array of pointers.
Thank you.

Just use an actual initialization, not an assignment (arrays cannot be assigned to).
A::A() : handlers {&A::first, &A::second, &A::third, 0} {}

Related

Initializing array of Objects in C++ Composition

I wanted to design a composition using C++ as shown below:
#define NUMBER (4)
class wheel {
int radius;
public:
wheel();
wheel(int);
//copy constructors prototype
//getters and setters prototypes
};
wheel::wheel() : radius(1) {}
wheel::wheel(int r) : radius(r) {}
//wheel class copy constructor definition
//wheel class setter and getter definitions
class car {
wheel fourwheels[NUMBER];
public:
car();
};
car::car() {
fourwheels[NUMBER] = {wheel(1), wheel(1), wheel(1), wheel(1)}; //error code
//wheel fourwheels[NUMBER] = {wheel(1), wheel(1), wheel(1), wheel(1)}; //non-error code
}
int main() {
car mycar;
return 0;
}
While compiling the code, I am getting the following error:
error: no match for 'operator=' (operand types are 'wheel' and '<brace-enclosed initializer list>')
Queries:
Why does this error occur ??
When I comment the error code line and uncomment the non-error code line, it works fine. Why do we have to add the type wheel for the array definition?
You are attempting to assign to an array element. And one that's out of range at that.
Using the constructor's initializer list, this will compile, though you should consider using STL containers rather than a raw array.
car::car() : fourwheels{wheel(1), wheel(1), wheel(1), wheel(1)}
{
}
The code you had commented out "worked" because it declared and initialized a new array of four wheels.
Since the default constructor for wheel provides a radius of 1, you could also write:
car::car() : fourwheels{wheel(), wheel(), wheel(), wheel()}
{
}
But, if we used std::array to hold our wheels, we can simplify this further, as the elements of fourwheels will be initialized using the wheel type's default constructor, which we don't have to write.
class car {
std::array<wheel, NUMBER> fourwheels;
};
Why does this error occur ??
Raw arrays are not copy-assignable. That is, the following will not work:
int nums[4] = {};
nums = {1, 2, 3, 4};
That is essentially what you're trying to do in your car constructor. Instead, you need to initialize the fourwheels member in the member initialization list:
car::car()
: fourwheels{wheel(1), wheel(1), wheel(1), wheel(1)}
{}
When I comment the error code line and uncomment the non-error code line, it works fine. Why do we have to add the type wheel for the array definition ??
Because you're not initializing your car class's member there. You're declaring and initializing a different array, also named fourwheels that is local to the constructor body. The class member remains default-initialized.

Initialising a vector of structs containing function pointers gives "no viable overloaded '=' "

I am trying to write a chip CPU emulator and implementing its instruction table as a vector of structs where each struct contains a value and a function pointer to a particular operation. My compiler (clang++) however gives me the error:
no operator "=" matches these operands -- operand types are: std::__1::vector<A::someStruct, std::__1::allocator<A::someStruct>> = {...}
and:
no viable overloaded '='
for the line func_table = {{1,&A::func1},{2,&A::func2}};
I'm using the exact same syntax used in a similar project on GitHub but I still get these errors. It only seems to be a problem initialising with structs of non-null function pointers. I'm very new to programming with C++ so i'd love to know what I'm misunderstanding. Below is an example of the header and source file
#include <vector>
class A{
public:
A();
private:
struct someStruct{
int a = 0;
void (*fptr)(void) = nullptr;
};
std::vector<someStruct> func_table;
void func1();
void func2();
};
#include "tutorial.h"
A::A(){
func_table = {{1,&A::func1},{2,&A::func2}}; // two entries here, but the table is 512 long
}
void A::func1(){
// something
}
void A::func2(){
// something else
}
int main(){
A example;
return 0;
}
I don't understand what these errors mean and why brace initialisation seems to have a problem with function pointers. I would really appreciate any input on this. Thanks
The structure definition should look like
struct someStruct{
int a = 0;
void (A::*fptr)(void) = nullptr;
};
because you are trying to use member functions of the class A as initializers.
A::A(){
func_table = {{1,&A::func1},{2,&A::func2}};
}
That is you have to declare pointers to class members.

Use the functions of a vector objects using a pointer

1).Why did I get this error? What is the correct syntax?
2).Is there a way to write the same code without using the library "vector"?
#include <vector>
myClass()
{
public:
myClass(int x,int y);
void doThis()
{
//Something
}
}
int main(void)
{
std::vector<myClass>*ex_vector = new std::vector<myClass(5,myClass{10,10});
ex_vector[0]->doThis(); //Error Here
delete []ex_vector;
}
I get this error:
error: base operand of '->' has non-pointer type 'std::vector<myClass>'
The correct syntax is
(*ex_vector)[0].doThis();
Also, you should delete ex_vector; and not delete[] ex_vector; since the type of the new was not a raw array type.
However, there's rarely a good reason to new a std::vector. Just use a plain object.

C++: multidimensional array initialization in constructor

I want to use a two dimensional array of constant size as a class member in C++. I have problems initializing it in the constructor though.
Here are my non-working tries:
1.)
class A {
public:
int a[2][2];
A();
};
A::A() {
a = {{1,2},{2,4}};
}
yields: error: assigning to an array from an initializer list
2.)
class A {
public:
int a[2][2];
A();
};
A::A() {
int b[2][2] = {{1,2},{2,4}};
a = b;
}
yields: invalid array assignment
3.)
class A {
public:
int **a;
A();
};
A::A() {
int b[2][2] = {{1,2},{2,4}};
a = b;
}
yields: cannot convert ‘int [2][2]’ to ‘int**’ in assignment
I come from C background. I know that I could use std::vector and I am aware of the disadvantages this approach has but since this is an exercise for me I would like to know how to get it working with plain arrays. I should add that I want to work on this array later on. I want to change the stored values but not the size. Maybe that matters as well (I figured a const at the right place could help somehow?).
If you have C++11, you can use this syntax in the constructor definition:
A() : a{{1,2}, {3, 4}} {}
If you don't have C++11, you will need to stick to the wicked old ways:
A() {
a[0][0] = 1;
// etc
}
The first example also uses the constructor init-list, which should always be used to initialize members instead of intializing them in the constructor body.
various multidimensional array in constructor by example:
// int array1[1];
A() : array1{0} {}
// int array2[2][2];
A() : array2{{0}} {}
// int array3[3][3][3];
A() : array3{{{0}}} {}
Try this, it works for bidimensional array (in standard C++):
class A {
public:
int a[2][2];
A();
};
typedef struct{ int a[4]; } array_t;
A::A() {
int at[2][2] = {{1,2},{2,4}};
*(array_t*)a = *(array_t*)at;
}
Ciao
Angelo
Your first variant is extremely close to the right C++11 syntax:
A::A()
: a{{1,2},{2,4}}
{
}
To complement the previous answers (you guys are so fast):
What you were trying to do in case 1 and 2 is array assignment, not permitted, as compiler says ;
But I would like to draw your attention to your third case, that's a grave misconception, specially coming from C as you say.
Assigning to a a pointer to a local variable?

Error with implement map within template c++

I need to use a map with various type within es int,int or char,int or char,char....
This is my c++ code:
#include <iostream>
#include<map>
using namespace std;
template< class A, class B >
class MyClass {
private:
std::map<A,B> DatMap;
public:
MyClass<K,T>(){
DatMap = 0;
}
~MyClass(){
delete DatMap;
}
void DatInsert( A k ,B v ) {
DatMap.insert( std::pair<A,B>( k, v) );
}
};
int main(){
DatMap<int,int> datmap1();
diz1.DatInsert();
}
I found this error on: diz1.DatInsert(); line
the error is:
error: request for member ‘DatInsert’ in ‘datmap1’, which is of non-class type ‘DatMap<int, int>()’|
What am I doing wrong?
This is a function declaration:
// functon datamap1, returns DatMap<int, int>
DatMap<int,int> datmap1();
You need
DatMap<int,int> datmap1;
Alternatively, this syntax is valid since C++11
DatMap<int,int> datmap1{};
Vlad and Jauncho make good points but have both missed another error
DatMap<int,int> datmap1(); isn't valid also because there is no public type DatMap exposed. The class is MyClass
You should be saying:
MyClass<int,int> datmap1; // or datmap1{};
There are several errors in the code.
For example identifiers K and T used in this code snippet
MyClass<K,T>(){
DatMap = 0;
}
are undefined. Also the assignment DataMap by zero is invalid.
You shall not delete DatMap in destructor
~MyClass(){
delete DatMap;
}
because DatMap is not a pointer.
These both statements in main
DatMap<int,int> datmap1();
diz1.DatInsert();
are invalid. The first one is a declaration of a function that shall not be compiled. And the second statement contains call of member function DatInsert without arguments. You defined the function as having two parameters
void DatInsert(A k ,B v){
DatMap.insert(std::pair<A,B>(k,v));
}
so you need to provide two arguments.