Issue in passing argument to std::function for vector of functions - c++11

I'm trying to create a vector of std::function and then pass that vector to a function. I also need to pass arguments to the function objects, so I'm using std::bind. Here is the code:
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void execute(vector<function<void (int)>>& fs) {
for (auto& f : fs)
f();
}
void func(int k) {
cout << "In func " << k << endl;
}
int main()
{
int i = 1;
vector<function<void (int)>> x;
auto f1 = bind(func, i);
//f1(); // this does call intended function
x.push_back(f1);
execute(x);
}
but this gives following error:
function_tmpl.cpp: In function ‘void execute(std::vector >&)’:
function_tmpl.cpp:14:5: error: no match for call to ‘(std::function) ()’
f();
^
In file included from function_tmpl.cpp:1:0:
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/functional:2142:11: note: candidate is:
class function
^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/functional:2434:5: note: _Res std::function::operator()(_ArgTypes ...) const [with _Res = void; _ArgTypes = {int}]
function::
^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/functional:2434:5: note: candidate expects 1 argument, 0 provided
If I call f() inside main(), that works fine, which means that the function has bound with the arguments, but it's not working when passed to another function as argument

You are using a vector of void functions with a single int argument: vector<function<void (int)>>, but you are actually pushing void(void) functions. All you need to do is to change the element type of the vector to vector<function<void (void)>>. Bind works roughly like this:
given:
void f1(int i) { printf("%d", i); }
bind(f1, 1) returns a new function f2:
void f2()
{
f1(1);
}
and since you are pushing f2, the vector should store void(void) functions.

After binding, the type of function has become to void(). So change the type of vector to vector<function<void ()>>, you'll get it.
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void execute(vector<function<void ()>>& fs) {
for (auto& f : fs)
f();
}
void func(int k) {
cout << "In func " << k << endl;
}
int main()
{
int i = 1;
vector<function<void ()>> x;
auto f1 = bind(func, i);
x.push_back(f1);
execute(x);
}
result:
In func 1
LIVE

The return type of std::bind is unspecified. Hence you cannot expect std::bind to return a variable of same type as std::function<void(int)>. Use decltype and templates to resolve.
Here is an example
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template <typename T>
void execute(vector<T>& fs) {
for (auto& f : fs)
f();
}
void func(int k) {
cout << "In func " << k << endl;
}
int main()
{
int i = 1;
auto f1 = bind(func, i);
vector<decltype(f1)> x; //deduce type of f1
x.push_back(f1);
execute(x);
}

f is of type
function<void (int)>&
so the compiler expects you to provide a parameter, like this:
f(1)

Related

Using recursion inside a called constructor

Don't know where to begin on how to use recursion within a called constructor.
recursion.cpp
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
#include "MinilabRecursion.h"
MinilabRecursion::puzzleRecurse(int n)
{
int recurse(n) // <--- Don't know what to do here
{ //error: expected ',' or ';' before '{' token
if( n == 0 )
{
return 1;
}
if( n >= 1 )
{
return recurse(n - 1) + 4 * n;
}
}
} //error: expected '}' at end of input
driver.cpp
#include <iostream>
#include <string>
using namespace std;
#include "MinilabRecursion.h"
{
cout << "puzzleRecurse(1) returns: " << MinilabRecursion::puzzleRecurse(1) << endl;
cout << "puzzleRecurse(7) returns: " << MinilabRecursion::puzzleRecurse(7) << endl;
cin.get();
return 0;
}
recursion.h
#ifndef MINILABRECURSION_H
#define MINILABRECURSION_H
#include <iostream>
#include <string>
using namespace std;
class MinilabRecursion
{
public:
static int puzzleFormula(int n);
static int puzzleLoop(int n);
static int puzzleRecurse(int n);
};
#endif
The if statements within recursion.cpp should give me the desired outcome, but I do not know how to use recursion in this context.
I'm not sure I can make sense out of the code you posted. It seems you want to do the following, but are confused about some of the C++ basics:
int MinilabRecursion::puzzleRecurse(int n)
{
if (n == 0) {
return 1;
}
return puzzleRecurse(n - 1) + 4 * n;
}

Boost::spirit::qi - How do I build a parse rule that sets a property?

I'd like to build a rule that takes in a few parameters from a parsed line then sets a few as constant. Is that possible? An (invalid) example to illustrate what I'm trying to do is below. I think I'm using _r1 incorrectly here, but I'm not sure how to get at the right thing. Assume I don't want to just modify r before sending it into the parser.
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_plus.hpp>
#include <boost/spirit/include/qi_sequence.hpp>
#include <boost/spirit/include/qi_string.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/phoenix/bind/bind_function.hpp>
#include <string>
using namespace boost::spirit::qi;
struct Sample
{
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
const rule<std::string::const_iterator, Sample()> AnythingAndOne = int_ >> eps[_r1.b = 1] >> eoi;
int main()
{
std::string z("3");
Sample r;
parse(z.begin(), z.end(), AnythingAndOne, r);
return 0;
}
Again, with reference to Boost Spirit: "Semantic actions are evil"? I'd avoid the semantic action.
You can directly synthesize a particular attribute value by using qi::attr:
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
struct Sample {
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
namespace qi = boost::spirit::qi;
int main()
{
std::string const z("3");
Sample r;
qi::rule<std::string::const_iterator, Sample()> AnythingAndOne
= qi::int_ >> qi::attr(1) >> qi::eoi;
if (parse(z.begin(), z.end(), AnythingAndOne, r))
std::cout << "Parsed: " << boost::fusion::as_vector(r) << "\n";
else
std::cout << "Parse failed\n";
}
Prints
Parsed: (3 1)

what is the purpose of template class in c++

I cannot understand what is template class used for?
I am new to c++. Can I get a detail explanation.
// constructing unordered_sets
#include <iostream>
#include <string>
#include <unordered_set>
template<class T>
T cmerge (T a, T b) { T t(a); t.insert(b.begin(),b.end()); return t; }
std::unordered_set<std::string> second ( {"red","green","blue"} ); // init list
std::unordered_set<std::string> third ( {"orange","pink","yellow"} ); // init list
std::unordered_set<std::string> fourth ( second );
std::unordered_set<std::string> fifth ( cmerge(third,fourth) ); // move
C++ template class/function is basically a generic class/function i.e., you just have to define the class or function once and you can use this definition for different data types(int,char,float etc).
for Example:-
#include <iostream>
using namespace std;
// One function works for all data types. This would work
// even for user defined types if operator '>' is overloaded
template <typename T>
T myMax(T x, T y)
{
return (x > y)? x: y;
}
int main()
{
cout << myMax<int>(3, 7) << endl; // Call myMax for int
cout << myMax<double>(3.0, 7.0) << endl; // call myMax for double
cout << myMax<char>('g', 'e') << endl; // call myMax for char
return 0;
}

Reversing a string using only iostream, fstream, string and vector

I just started working with C++ about a week ago so I don't know much about the language. I am working on creating a program that inputs a text file and then reverses all of the lines.
So an input of:
"abc"
"123"
Would be:
"cba"
"321"
I can figure out how to input the lines from the file, but I am having trouble with my reverse function. I have tried to just print out each individual character as a string using substring, starting from length - 1 and ending at 0. But this does not seem to be working. When I run the program, I get these errors that I don't understand.. Any ideas as to what is going wrong?
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
void reverse(string input) {
for((int x=input.length()-1); x=0; x--)
cout << input.substr(x);
}
cout << endl;
}
int main()
{
string line;
ifstream myFile;
myFile.open("reverse_input.txt");
while(getline(myFile, line)) {
reverse(line);
}
return 0;
}
There are couple syntax errors in your code that the compiler was complaining
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
void reverse(string input) {
for( unsigned int x= (input.length()-1); x>=0; x--) { //Missing {, extra (), >= insteadof = 0
cout << input[x] << flush;
}
cout << endl;
}
int main()
{
string line;
ifstream myFile;
myFile.open("reverse_input.txt");
while(getline(myFile, line)) {
reverse(line);
}
return 0;
}

Search Function returns wrong results

I have made a function for my program that reads from a text file, adds content to a vector and then search in that vector. The Problem is that even if the file is empty it shows that it found something, on the other side if i change return value to 0 it does not give results at all!
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
vector<string> contacts;
//This function returns at what index the name is found
int searchContact(string contactToSearch)
{
string entry;
ifstream input;
input.open("contacts.txt");
while (input.good())
{
while (getline(input, entry))
{
contacts.push_back(entry);
}
input.close();
}
for(int i = 0; i < contacts.size(); i++)
{
if(contactToSearch == contacts[i])
{
//Found => Returning index rest of program can see index
return i;
}
}
return 1;
}
I have just refactored your code a little. Further improvements are possible, but to begin with
1) You dont need a while for input.good()
2) You were trying to return 0 and 1 which are indeed valid positions where the string could have been present in the vector
All these aside, I still think your code might not properly populated the array The reasons for this maybe :- case sensitive comparison, reading incorrect file, binary file.. etc..
Here is a refactored code that you could use
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
void readContacts(const string &fileName inputFileName, vector<string> &contacts){
string entry;
ifstream input;
input.open(inputFileName);
if (input.good())
{
while (getline(input, entry))
contacts.push_back(entry);
input.close();
}
}
int searchContact(const string &contactToSearch, vector<string> &contacts)
{
for (int i = 0; i < contacts.size(); i++)
{
if (contactToSearch == contacts[i])
return i;
}
return -1;
}
int main(){
vector<string> contacts;
// This needs to be filled in with the contact name u want to search
string contactToSearch;
readContacts("contacts.txt", contacts);
int index = searchContact(contactToSearch, contacts)
if (index != -1)
cout << "Found Contact " << contactToSearch" at location " << index << endl;
else
cout << "Could Not find contact " << contactToSearch << endl;
}

Resources