Why Do I get this error on vector initialisation? - c++

I have a problem with vector declaration and initialization in a
class constructor. I have a Station.h and Station.cpp files of a class and I recall it in main :
Station.h
#ifndef STATION_H
#define STATION_H
#include <vector>
class Station
{
public:
int num_bin;
int num_staz;
vector<int> binari; //here already gives me error! Vector does not name a type
Station(int num_staz, int num_bin);
virtual ~Station();
Station(const Station& other);
protected:
private:
};
Then I want to initialize the vector in the constructor of .cpp like that:
Station.cpp
#include "Station.h"
using namespace std;
Station::Station(int num_staz, int num_bin)
{
this->num_bin = num_bin;
this->num_staz = num_staz;
this->binari(num_bin); //here I want to create a vector of num_bin size
}
and then call it in main like that:
main.cpp
#include <iostream>
#include "Station.h"
using namespace std;
int main()
{
Station staz1(2,3);
staz1.binari.push_back(300); // error! class Station has no member binari
staz1.binari.push_back(250);
staz1.binari.push_back(150);
return 0;
}
Where am I making a mistake?

this->binari(num_bin); //here I want to create a vector of num_bin size
The function you need to use is std::vector::resize().
this->binari.resize(num_bin);
It will be better to initialize the object with the appropriate size as:
Station::Station(int num_staz, int num_bin) : num_bin(num_bin),
num_staz(num_staz),
binari(num_bin)
{
}

this->binari(num_bin); This doesn't work because it is not an initialization that is why it doesn't work.
To make this work use it in in-class initialization list:
Station::Station(int num_staz, int num_bin) :
num_bin(num_bin),
num_staz(num_staz),
binari(num_bin)
{
}

Related

initializing a static (non-constant) variable of a class.

I have TestMethods.h
#pragma once
// strings and c-strings
#include <iostream>
#include <cstring>
#include <string>
class TestMethods
{
private:
static int nextNodeID;
// I tried the following line instead ...it says the in-class initializer must be constant ... but this is not a constant...it needs to increment.
//static int nextNodeID = 0;
int nodeID;
std::string fnPFRfile; // Name of location data file for this node.
public:
TestMethods();
~TestMethods();
int currentNodeID();
};
// Initialize the nextNodeID
int TestMethods::nextNodeID = 0;
// I tried this down here ... it says the variable is multiply defined.
I have TestMethods.cpp
#include "stdafx.h"
#include "TestMethods.h"
TestMethods::TestMethods()
{
nodeID = nextNodeID;
++nextNodeID;
}
TestMethods::~TestMethods()
{
}
int TestMethods::currentNodeID()
{
return nextNodeID;
}
I've looked at this example here: Unique id of class instance
It looks almost identical to mine. I tried both the top solutions. Neither works for me. Obviously I'm missing something. Can anyone point out what it is?
You need to move the definition of TestMethods::nextNodeID into the cpp file. If you have it in the header file then every file that includes the header will get it defined in them leading to multiple defenitions.
If you have C++17 support you can use the inline keyword to declare the static variable in the class like
class ExampleClass {
private:
inline static int counter = 0;
public:
ExampleClass() {
++counter;
}
};

Cannot declare array of strings as class member

I could not declare an array of strings in my class. Below my class definition:
class myclass{
public:
int ima,imb,imc;
string luci_semaf[2]={"Rosso","Giallo","Verde"};
};
and my main file
#include <iostream>
#include <fstream>
#include "string.h"
#include <string>
using namespace std;
#include "mylib.h"
int main() {
return 0;
}
Why do I get the following warnings / error?
You have two problems: The first is that you can't initialize the array inline like that, you have to use a constructor initializer list. The second problem is that you attempt to initialize an array of two elements with three elements.
To initialize it do e.g.
class myclass{
public:
int ima,imb,imc;
std::array<std::string, 3> luci_semaf;
// Without C++11 support needed for `std::array`, use
// std::string luci_semaf[3];
// If the size might change during runtime use `std::vector` instead
myclass()
: ima(0), imb(0), imc(0), luci_semaf{{"Rosso","Giallo","Verde"}}
{}
};
You can not initialize data member.
You can write like this:
class myclass{
public:
myclass() {
luci_semaf[0] = "Rosso";
luci_semaf[1] = "Giallo";
luci_semaf[2] = "Verde";
}
private:
int ima,imb,imc;
string luci_semaf[3];
};
You can assign the values of the array in the Сonstructor
You're declaring an array of size 2 but providing 3 strings!
Try storing the elements in vector of strings, in c++ vectors are used more often.
class myclass{
public:
int ima,imb,imc;
std::vector<std::string> strings;
myclass() {
strings.push_back("blabla");
}
};

Cant create a vector with a specified size

I'm trying to create a vector with a specific size, of 255 (max)..
It doesnt work for me, like I see in examples over the internet...
I'm using Microsoft Visual C++ 2012...
I have the current code :
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
using namespace std;
const int MAX = 255;
class test
{
vector <string> Name(MAX);
};
int main()
{
system("PAUSE");
}
It gives me 2 errors :
Error 1 error C2061: syntax error : identifier 'MAX'
2 IntelliSense: variable "MAX" is not a type name
Thanks for your help!
That's not valid syntax for a class declaration. Try:
class test
{
vector <string> Name;
test() : Name(MAX) {}
};
You can write vector <string> Name(MAX); when you create a variable (in your case, you're declaring a member). For example:
int main()
{
vector <string> Name(MAX);
}
would be perfectly valid.
You can't pass arguments to the std::vector constructor int the class declaration. You should put that in the constructor for your class, like this, which utilizes does it via an initializer list:
class test
{
std::vector<std::string> Name;
public:
test():
Name(MAX)
{
}
};
You cannot initialize a data member inside the class declaration like this. Use the member initialization list in your constructor of the class to initialize vector<string> Name.
test::test
:Name(MAX)
{
//
}
Your main would be like this.
test t1 ;
It would automatically call the constructor and all the fields of t1 would be created, including vector<string> Name.

C++ compile time error: expected identifier before numeric constant

I have read other similar posts but I just don't understand what I've done wrong. I think my declaration of the vectors is correct. I even tried to declare without size but even that isn't working.What is wrong??
My code is:
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#include <cmath>
using namespace std;
vector<string> v2(5, "null");
vector< vector<string> > v2d2(20,v2);
class Attribute //attribute and entropy calculation
{
vector<string> name(5); //error in these 2 lines
vector<int> val(5,0);
public:
Attribute(){}
int total,T,F;
};
int main()
{
Attribute attributes;
return 0;
}
You cannot do this:
vector<string> name(5); //error in these 2 lines
vector<int> val(5,0);
in a class outside of a method.
You can initialize the data members at the point of declaration, but not with () brackets:
class Foo {
vector<string> name = vector<string>(5);
vector<int> val{vector<int>(5,0)};
};
Before C++11, you need to declare them first, then initialize them e.g in a contructor
class Foo {
vector<string> name;
vector<int> val;
public:
Foo() : name(5), val(5,0) {}
};
Initializations with (...) in the class body is not allowed. Use {..} or = .... Unfortunately since the respective constructor is explicit and vector has an initializer list constructor, you need a functional cast to call the wanted constructor
vector<string> name = decltype(name)(5);
vector<int> val = decltype(val)(5,0);
As an alternative you can use constructor initializer lists
Attribute():name(5), val(5, 0) {}
Since your compiler probably doesn't support all of C++11 yet, which supports similar syntax, you're getting these errors because you have to initialize your class members in constructors:
Attribute() : name(5),val(5,0) {}

How to invoke non-default constructor for template class?

I have the following code structure (Resource and Parameter are empty classes):
Solver.cpp
#include "Solver.h"
#include "ValueFunction.h"
using namespace std;
template<typename T>
Solver<T>::Solver(vector<vector<Resource> >& resources, const Parameter& params) :
states(resources.size()) {
for (int i=0; i<resources.size(); i++) {
states[i] = State<T>(resources[i], params);
}
}
// Explicit class declaration
template class Solver<ValueFunction>;
Solver.h
#ifndef SOLVER_H_
#define SOLVER_H_
#include <vector>
#include "Resource.h"
#include "Parameter.h"
#include "State.h"
template<typename T>
class Solver {
public:
Solver(
std::vector<std::vector<Resource> >& resources,
const Parameter& params
);
private:
std::vector<State<T> > states;
};
#endif /* SOLVER_H_ */
State.cpp
#include "State.h"
#include "ValueFunction.h"
using namespace std;
template<typename T>
State<T>::State(vector<Resource>& _resources, const Parameter& params) :
resources(_resources), valfuncs(_resources.size(), T(params)) {
}
template class State<ValueFunction>;
State.h
#ifndef STATE_H_
#define STATE_H_
#include <vector>
#include "Parameter.h"
#include "Resource.h"
template<typename T>
class State {
public:
State() {};
State(std::vector<Resource>& _resources, const Parameter& params);
~State() {};
private:
std::vector<Resource> resources;
std::vector<T> valfuncs;
};
#endif /* STATE_H_ */
ValueFunction.cpp
#include "ValueFunction.h"
ValueFunction::ValueFunction(const Parameter& _params) : params(_params) {
}
ValueFunction.h
#ifndef VALUEFUNCTION_H_
#define VALUEFUNCTION_H_
#include "Parameter.h"
class ValueFunction {
public:
ValueFunction(const Parameter& _params);
private:
const Parameter& params;
};
#endif /* VALUEFUNCTION_H_ */
With the following call:
#include "Solver.h"
#include "State.h"
#include "ValueFunction.h"
#include "Parameter.h"
using namespace std;
int main(int argc, char *argv[]) {
Parameter params;
vector<vector<Resource> > resources(4);
Solver<ValueFunction> sol(resources, params);
return 0;
}
And I get the following error:
Solver.cpp:18:16: instantiated from here
ValueFunction.h:6:21: error: non-static reference member ‘const Parameter& ValueFunction::params’, can't use default assignment operator
How can I invoke the non-default constructor for ValueFunction correctly, or is there an other way to initialize an std::vector with a non-default constructor (passing a constant reference)?
Update
The error is explained in this post. But the workaround for my problem is not entirly clear. Any suggestions?
You are initializing the states of Solver using the form of the constructor that calls the default constructor of the vector members. You can pass in a second parameter to the vector constructor for states of type State<T>, and the vector will use the copy constructor to initialize the vector elements using that parameter as the source. Your loop in the Solver constructor will still work to provide the values you actually want within the states vector.
A reference cannot be initialized by the compiler generated default constructor. This is because it is the job of the default constructor to initialize the object, but a reference needs something to refer to. Just as you get an error declaring a reference variable with no initializer, the default constructor encounters the same problem.
int &r; // this is an error
int i;
int &rr = i; // this is proper
Using the copy constructor version of the vector constructor helps you to avoid the problem, because the copy constructor initializes the reference with the value of the object it is copying. In this form of initializing a vector, each of the elements in states gets set to the same value as the first element.
...
: states(resources.size(), State<T>(resources[0], params))
...
Perhaps the better way to go is to use the default constructor for the vector itself, and use reserve and push_back to add elements to the vector. This is better because it avoids creating any State<T> objects at all until it is actually added to the vector.
...
: states()
...
states.reserve(resources.size());
for (int i...) {
states.push_back(State<T>(resources[i], params));
}
...
A third approach that would sort of allow your original code to work the way it was written is to define your own default constructor for ValueFunction that initializes the params member to something (perhaps the dreaded global).
class ValueFunction {
public:
ValueFunction (); // define our own default constructor
...
};
const Parameter global_default_parameter;
ValueFunction::ValueFunction () : params(default_parameter) {}