Questions on iostream and initializer_list - c++

I have received the following error for the following code on Visual Studio Code for Mac.
ArrayStudy.cpp:21:19: error: cannot deduce type of initializer list because std::initializer_list was not found; include <initializer_list>
for (auto x : {10,21,32,43,54,65})
I included #include <initializer_list> after noting it was absent, but continued to receive the error. I'm using Apple clang version 13.0.0 (clang-1300.0.29.30).
At this point I am stumped. Can someone help me get this code running with a short explanation of what I missed?
#include <iostream>
#include <string>
#include <fstream>
#include <initializer_list>
void print();
int main(){
print();
}
void print() {
int v[] = {0,1,2,3,4,5,6,7,8,9};
for (auto x : v)
cout << x << '\n';
for (auto x : {10,21,32,43,54,65})
cout << x << '\n';
}

Related

Struggling to create a Boost-Bimap containing std::bitset

I have a number of strings and their bitset equivalents. I need to be able to look up equivalents in both directions, i.e. "str to bitset" and "bitset to str". I believe boost-bimap would be the right container for this job.
I managed to get this to work with strings and integers but my string / bitset bimap does not compile. I am using VS2019 with the latest boost release.
Integer example works:
#include <boost/bimap.hpp>
#include <string>
#include <iostream>
int main()
{
typedef boost::bimap<std::string, int> bimap_str_int_t;
bimap_str_int_t bimap1;
bimap1.insert(bimap_str_int_t::value_type("A", 1));
std::cout << bimap1.left.at("A") << '\n'; //prints 1
std::cout << bimap1.right.at(1) << '\n'; // prints A
}
Bitset example fails to compile:
#include <boost/bimap.hpp>
#include <string>
#include <iostream>
#include <bitset>
int main()
{
typedef std::bitset<3> bitset_t;
typedef boost::bimap<std::string, bitset_t> bimap_str_bitset_t;
bimap_str_bitset_t bimap2;
bitset_t bits{ "010" };
bimap2.insert(bimap_str_bitset_t::value_type("A", bits));
std::cout << bimap2.left.at("A") << '\n';
std::cout << bimap2.right.at(bits) << '\n';
}
The bitset example creates the following compiler error:
boost_test.cpp(20): message : see reference to class template instantiation 'boost::bimaps::bimap' being compiled
I am not sure how to fix this and would greatly appreciate any hints.
The issue is that std::bitset has no operator< - one of the requirements of any STL-like ordered collection.
To fix this, you need to supply a comparison function - here's one way you might try:
#include <boost/bimap.hpp>
#include <string>
#include <iostream>
#include <bitset>
typedef std::bitset<3> bitset_t;
struct compare_bitset {
bool operator()(const bitset_t& x, const bitset_t& y) const {
return x.to_ulong() < y.to_ulong();
}
};
int main()
{
using bitset_set = boost::bimaps::set_of<bitset_t, compare_bitset>;
typedef boost::bimap < std::string, bitset_set> bimap_str_bitset_t;
bimap_str_bitset_t bimap2;
bitset_t bits{ "010" };
bimap2.insert(bimap_str_bitset_t::value_type("A", bits));
std::cout << bimap2.left.at("A") << '\n';
std::cout << bimap2.right.at(bits) << '\n';
}

BOOST_PP_REPEAT with boost::fusion::size

I want to iterate in compile time over struct and write to output number of iteration. Just to mention - in real case I will pass some more parameters in data.
#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
struct MyStruct
{
int x;
int y;
};
BOOST_FUSION_ADAPT_STRUCT(
MyStruct,
(int, x)
(int, y)
)
#define PRINT(unused, number, data) \
std::cout << number << std::endl;
int main()
{
MyStruct s;
std::cout << boost::fusion::size(s) << std::endl;
//line below works - it iterate and write output
BOOST_PP_REPEAT(2, PRINT, "here I will pass my data")
//this won't compile
//BOOST_PP_REPEAT(boost::fusion::size(s), PRINT, "here i will pass my data")
}
How to fix problematic line so it will work when I will add more members in structure? I need solution for C++03 :(
Instead of using BOOST_PP_REPEAT, you can use the boost::fusion::for_each which goes through every element. example:
#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
struct MyStruct {
int x;
int y;
};
BOOST_FUSION_ADAPT_STRUCT(
MyStruct,
(int, x)
(int, y)
)
template<typename Data>
struct PrintWithData {
PrintWithData(Data data) : data(data) {}
template<typename T>
operator()(const T& thingToBePrinted)
{
std::cout << thingToBePrinted << std::endl;
}
Data data;
};
int main()
{
MyStruct s;
//this will compile
boost::fusion::for_each(s, PrintWithData<std::string>("here I will pass my data"));
}
Here is exact solution for this problem (asked more general question later, and found answear which solve this problem too): https://stackoverflow.com/a/31713778/4555790

Solaris CC 12.4 compiler bug?

I can use array pointers as iterators in for_each but when I try to do the same using distance, the Solaris 12.4 compiler complains about not finding a match.
Here is my code:
#include <iterator>
#include <algorithm>
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
using std::hex;
struct Bob {
char q[16];
};
Bob stuff[16];
void DoBob(Bob& bob) {
cout << "BOB! " << hex << &bob << endl;
}
int main() {
// int ret = std::distance(&stuff[0], &stuff[3]);
// The line above causes the Solaris C++ compiler to complain:
//"main.cc", line 22: Error: Could not find a match for std::distance<_ForwardIterator, _Distance>(Bob*, Bob*) needed in main().
std::for_each(&stuff[0], &stuff[3], DoBob);
return 0;
}
I tend not to like to blame the compiler. Am I doing something wrong or is this a problem with the Solaris compiler?

C++ initializer_list parameters - can they have default values?

The following code causes a C1001 internal error in Visual Studio 2013 (v12.0.30501.00 Update 2) - should I expect it to work? (downloadable here)
I was expecting to be able to call the func function without a vals argument and have the default of {10.0} used.
Any help appreciated!
C.hpp:
#include <string>
#include <initializer_list>
#pragma once
class C {
public:
void func(std::string str, std::initializer_list<double> vals = { 10.0 });
};
C.cpp:
#include "stdafx.h"
#include "C.hpp"
#include <iostream>
using namespace std;
void C::func(std::string str, std::initializer_list<double> vals){
cout << "str is " << str << endl;
for (double v : vals){
cout << v << endl;
}
}
initializer_list_default_parameter.cpp:
#include "stdafx.h"
#include "C.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
C inst;
inst.func("name"); // this line causes a C1001 error with MSVC 2013
//inst.func("name", { 4.3 }); this line compiles
return 0;
}
Yes, initializer_list parameters can have default values, but there's a bug in the MSVC 2013 x86 compiler meaning they're not supported (http://connect.microsoft.com/VisualStudio/Feedback/details/925540).

how can I write a list of pair?

I am currently trying to write a list of pairs. my code is :
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <list>
using namespace std;
list<pair<string,char>> listPair;
list<pair<string,char>>::iterator it;
void printStars(list<pair<string,char>> listPair)
{
for (it=listPair.begin(); it != listPair.end(); it++)
cout << it->first <<" ";
cout << endl;
}
int main()
{
pair<string,char> mypair;
listPair.push_back(make_pair("bib",'a'));
listPair.push_back(make_pair("bob",'b'));
for_each(listPair.begin(), listPair.end(), printStars);
return 0;
}
Compilation fails with:
error C2664: 'void (std::list<_Ty>)' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>' to 'std::list<_Ty>'
Can you please help me detect where exactly is the problem?
The functor you pass to std::for_each is expected to accept an element of the range you pass into std::for_each. Your last has pair<string,char> elements, so your functor should have a signature like: void printStars(const pair<string,char>& elem).
In addition, to pass a plain function to std::for_each you need to use std::ref or (on an old compiler) std::ptr_fun.
#include <iostream>
#include <algorithm>
#include <list>
#include <string> // missing include
#include <utility>
#include <functional>
using namespace std;
typedef list< pair<string,char> > list_t;
list_t listPair;
void printStars(list_t::reference x) // use a reference, otherwise you create a copy
{
cout << x.first << " " << x.second << endl;
}
int main()
{
pair<string,char> mypair;
listPair.push_back(make_pair("bib",'a'));
listPair.push_back(make_pair("bob",'b'));
for_each(listPair.begin(), listPair.end(), std::ref(printStars)); // C++11
for_each(listPair.begin(), listPair.end(), std::ptr_fun(&printStars)); // C++98
return 0;
}
Your problem is, your printStars() expects a list, however for_each passes it each item, not the actual list:
Working code :
#include <iostream>
#include <algorithm>
#include <iterator>
#include <list>
#include <string>
#include <utility>
list<pair<string,char> > listPair;
list<pair<string,char> >::iterator it;
void printStars(const pair<string,char> & listPair){ //notice the &, so it would pass by reference and not make a new copy of the pair.
cout << listPair.first << ' ';
}
int main() {
pair<string,char> mypair;
listPair.push_back(make_pair("bib",'a'));
listPair.push_back(make_pair("bob",'b'));
for_each(listPair.begin(), listPair.end(), printStars);
cout << endl;
return 0;
}