I'm having a hard time trying to understand how to use the <initializer_list> in C++. Let's pick a simple example:
I've got something like this:
using namespace std;
class TV{
vector<string> channels;
public:
TV(initializer_list<string> channels){}
}
Let's say this is my main:
int main(){
TV x({"BBC", "CNN"}, y({"SKYNEWS", "FOX", "CNN"});
return 0;
}
How can I create a constructor without default argument-count for strings?
One of the constructors of std::vector directly takes a std::initializer_list
vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );
So you can just initialize in your constructor
TV(std::initializer_list<std::string> _channels)
: channels(_channels)
{}
Also you should avoid declaring multiple variables on a single line, as your parentheses were mismatched, it would have been more obvious.
TV x{{"BBC", "CNN"}};
TV y{{"SKYNEWS", "FOX", "CNN"}};
Working demo
Your code is working fine.
There is braces misalignment in TV x({"BBC", "CNN"}), y({"SKYNEWS", "FOX", "CNN"}); ,while you declared. Adjusted and pasted the code below. It works.
#include <iostream>
#include <vector>
using namespace std;
class TV{
vector<string> channels;
public:
TV(initializer_list<string> channels1){
channels = channels1;
}
void printSize()
{
cout<<channels.size()<<endl;
}
};
int main(){
TV x({"BBC", "CNN"}), y({"SKYNEWS", "FOX", "CNN"});
x.printSize();
y.printSize();
return 0;
}
The output is
2
3
Related
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)
{
}
I am 4 hours-new to C++ and have hit a brick wall with string vectors. When trying to add multiple strings to a string vector, I keep erroring out. I'd like to use push_back.
I would also like to display this string vector, but I'm not sure how (I know how to display non-vectors). Given that I have not been able to add a string to a vector of strings, I did not attempt to display the vector of strings yet.
profile.hpp
#include <iostream>
#include <vector>
class Profile
{
private:
std::string name;
std::string city;
std::string country;
int age;
std::vector<std::string> hobbies;
public:
std::vector<std::string> add_hobbies(std::string new_hobbies);
};
profile.cpp
#include <iostream>
#include "profile.hpp"
Profile::Profile(std::string new_name, int new_age, std::string new_city, std::string new_country)
: name(new_name), age(new_age), city(new_city), country(new_country)
{}
void Profile::add_hobbies(std::string new_hobbies)
{
hobbies.push_back(new_hobbies);
}
app.cpp
#include <iostream>
#include "profile.hpp"
int main()
{
Profile sam("Sam Drakkila", 30, "New York", "USA");
sam.add_hobbies("Play golf", "Read books", "Eat tennis balls"); // This doesn't seem to work.
}
g++ app.cpp profile.cpp. Prints a massive log of errors.
You have the following problems in your code:
You have declared add_hobbies returns std::vector<std::string>,
but in definition you have returned void. Presumably, you should have declared as a void function as it seems to be a setter function.
Secondly, you are passing a number of strings instead of a single string which
you defined here:
void Profile::add_hobbies(std::string new_hobbies) //>>> as per defenition, only one string can be passed!
// ^^^^^^^^^^^^^^^^^^^^^^^^
If you want to pass an arbitrary number of strings, you could usestd::initializer_list<std::string> instead.
Thirdly, you are missing the constructor declaration in the header file. Add
in the definition of class profile.hpp
Profile(std::string new_name, int new_age, std::string new_city, std::string new_country);
Last but not least, you need to include the <string> header in
order to use std::string(credits #πάντα ῥεῖ)
That means, (See live online)
#include <iostream>
#include <vector>
#include <string> // std::string
#include <initializer_list> // std::initializer_list
class Profile
{
private:
// ... other members
std::vector<std::string> hobbies;
public:
// ... other member functions
void add_hobbies(std::initializer_list<std::string> new_hobbies)
//^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
hobbies.reserve(hobbies.size() + new_hobbies.size()); // reserve memory to avoid, unwanted reallocations
for (const auto& hobby : new_hobbies) hobbies.emplace_back(hobby);
}
};
int main()
{
Profile sam{};
sam.add_hobbies({ "Play golf", "Read books", "Eat tennis balls" }); // now works
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Alternatively using variadic templates and c++17 feature fold expression.
(See live online)
#include <iostream>
#include <vector>
#include <string> // std::string
#include <type_traits> // std::enable_if, std::is_same, std::common_type
using namespace std::literals;
class Profile
{
private:
// ... other members
std::vector<std::string> hobbies;
public:
// ... other member functions
template<typename... Args> // sfinae to restrict the Args type to be only std::string s
std::enable_if_t<std::is_same_v<std::common_type_t<Args...>, std::string>>
add_hobbies(Args&& ... args)
{
hobbies.reserve(hobbies.size() + sizeof...(Args));
(hobbies.emplace_back(std::forward<Args>(args)), ...);
}
};
int main()
{
Profile sam{};
sam.add_hobbies("Play golf"s, "Read books"s, "Eat tennis balls"s); // now works
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
You declare add_hobbies as returning a vector in your class declaration.
There are a few errors in your code:
Missing constructor declaration:
Profile(std::string new_name, int new_age, std::string new_city, std::string new_country);
Mismatch between return type of the declaration and definition of add_hobbies, should be void (since you're not returning anything).
void Profile::add_hobbies(std::string new_hobbies) { // ... }
You're also trying to pass 3 of them, while the function only has 1 parameter:
void add_hobbies(std::string const& h1, std::string const& h2, std::string const& h3);
// ...
void Profile::add_hobbies(std::string const& h1, std::string const& h2, std::string const& h3) {
hobbies.push_back(h1);
hobbies.push_back(h2);
hobbies.push_back(h3);
}
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");
}
};
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.
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) {}