I've the code:
#include <iostream>
using namespace std;
auto fn = ([](int x){
return [x](int y) {
return x * y;
};
});
int main() {
int i = fn(2)(4); // 8
cout << i << endl;
return 0;
}
This code works fine.
However, I want to call a second function later like:
auto i = fn(2);
i(4); //error: 'i' cannot be used as a function
Are there any way to call the last function later and then bind with the first call?
The following works as expected
#include <iostream>
using namespace std;
auto fn = [](int x){
return [x](int y) {
return x * y;
};
};
int main() {
auto i = fn(2)(4); // 8
cout << i << endl;
auto j = fn(2);
cout << j(4) << endl;
return 0;
}
ADD
By the way gcc 4.5 with -std=c++0x gives the following error if you use int instead of auto:
currying.cpp:17:17: error: cannot convert ‘<lambda(int)>::<lambda(int)>’ to ‘int’ in initialization
currying.cpp:19:16: error: ‘j’ cannot be used as a function
which is an "obvious" and useful information to get what's going wrong.
The result of fn is not an integer, so you cannot assign fn(2) to an integer (don't even know why that compiles).
You should be able to do auto i = fn(2);
This works for me:
int main() {
auto i = fn(2);
cout << i(4) << endl; // prints 8
return 0;
}
Related
Thank you all, I didn't even know about user-defined conversion function and how it works.
Why is it possible to use std::reference_wrapper<int>::operator+=, if such an operator does not exist, are there some implicit conversions?
#include <iostream>
#include <functional>
#include <boost/type_index.hpp>
using boost::typeindex::type_id_with_cvr;
template <typename C>
void test(C c)
{
c += 1;
}
int main()
{
int a = 3;
test(a);
std::cout << a << std::endl;
test(std::ref(a));
std::cout << a << std::endl;
}
Output:
3
4
To check that template works perfectly fine:
void test_2(std::reference_wrapper<int> c)
{
c += 1;
}
int main()
{
int a = 3;
test_2(std::ref(a));
std::cout << a << std::endl;
}
Output:
4
Still works as before. How is that possible?
Funny thing, that in auto d = b + c, d has an integer type.
int main()
{
auto b = std::ref(a);
auto c = std::ref(a);
auto d = b + c;
std::cout << type_id_with_cvr<decltype(d)>).pretty_name() << std::endl;
}
Output:
int
It's because it's implicitly convertible to a reference to T:
/* constexpr [c++20] */ operator T& () const noexcept;
In your case, it's implicitly convertible to an int&.
This ability to be implicitly convertible to an int& is also what would make it possible for you to define your function to take an int& while passing it a std::reference_wrapper<int>:
void test_2(int& c) // <--+
{ // |
c += 1; // |
} // |
int main() { // |
// ... // |
test_2(std::ref(a)); // >--+
}
For indexing I use std::unordered_map and std::map. Both of them throws compiling errors when using as follow:
std::unordered_map<std::function<bool(Ent*)>, int> var;
std::unordered_map fails due referencing deleted function
std::map fails due no < operator
The ideal solution for me would be to use a type of map, but if is a must to use another type of container, then it shouldn't be a problem
One way of having functions as container key is to wrap them into functor structure
#include <unordered_map>
#include <typeinfo>
struct FunctorSum {
int operator()(int x, int y) {
return x + y;
}
};
struct FunctorMult {
int operator()(int x, int y) {
return x * y;
}
};
int main() {
std::unordered_map<size_t, int> funcToInt;
funcToInt[typeid(FunctorSum).hash_code()] = 0;
funcToInt[typeid(FunctorMult).hash_code()] = 1;
return 0;
}
Here I used typeid as hash, but it can also be hardcoded into functor struct.
Another way is to use std::function::target_type to calculate hash of the function, which will work only with lambdas. But you can always wrap any function into lambda.
#include <iostream>
#include <functional>
using FuncType = std::function<bool(int)>;
bool x(int v) { return v == 0; }
std::string hash(FuncType f) {
return f.target_type().name();
}
int main() {
auto y = [](int v) { return v == 1; };
auto z = [](int v) { return v == 2; };
std::cout << "x: " << hash(x) << std::endl;
std::cout << "y: " << hash(y) << std::endl;
std::cout << "z: " << hash(z) << std::endl;
return 0;
}
Output
x: PFbiE
y: Z4mainEUliE_
z: Z4mainEUliE0_
I am trying to create a function that accepts variable number of arguments. But I am getting error in expression decltype(std::initializer_list::size_type) res1=0; as error: expected primary-expression before 'decltype'. The purpose is to declare appropriate variable type that can hold sum of the list (although this declaration will create big enough variable to hold all elements of the list only and not their sum). How can I do this?
Also, how can I make appropriate function return type to return res1 instead of void?
#include <iostream>
#include <initializer_list>
void sum1(std::initializer_list<int> lst1)
{
decltype(std::initializer_list::size_type) res1=0;
for(auto v1:lst1)
{
res1 += v1;
}
std::cout<<" sum = \n"<<res1;
}
int main()
{
sum1({1,2,3,4,5,6,7,8,9,10});
//auto b = sum1({1,2,3,4,5,6,7,8,9,10});
return 0;
}
size_type is not needed for anything in your function. The initializer_list has type int, therefore res1 should be an int and your return type should be int. If you really want to derive the value type from the initializer_list then do so like this:
#include <iostream>
#include <initializer_list>
auto sum1(std::initializer_list<int> lst1)
{
typename std::initializer_list<int>::value_type res1 = 0;
for(auto v1:lst1)
{
res1 += v1;
}
return res1;
}
int main()
{
sum1({1,2,3,4,5,6,7,8,9,10});
auto b = sum1({1,2,3,4,5,6,7,8,9,10});
std::cout << b << std::endl;
return 0;
}
If you want the function to be generic, in which case it is necessary to derive the value type, then the template function looks like this.
#include <iostream>
#include <initializer_list>
template<typename T>
auto sum1(std::initializer_list<T> lst1)
{
typename std::initializer_list<T>::value_type res1 = 0;
for(auto v1:lst1)
{
res1 += v1;
}
return res1;
}
int main()
{
sum1({1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.10});
auto b = sum1({1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.10});
std::cout << b << std::endl;
return 0;
}
Following is corrected code.
#include <iostream>
#include <initializer_list>
int sum1(std::initializer_list<int> lst1)
{
int res1=0;
for(auto v1:lst1)
{
res1 += v1;
}
return res1;
}
int main()
{
std::cout<<" sum = "<<sum1({1,2,3,4,5,6,7,8,9,10});
//auto b = sum1({1,2,3,4,5,6,7,8,9,10});
return 0;
}
You can see working here.
Note: You can change the type of res0 to long or other type if result is not in the limits of int. Also, Change the return type of function sum1 accordingly.
#include <iostream>
typedef std::function<bool(int)> set;
using namespace std;
set singletonSet(int a) {
return [&] (int x) { return (a == x); };
}
bool contains(set s, int test) {
return s(test);
}
int main() {
auto first = singletonSet(5);
auto r1 = contains(first, 10);
auto r2 = contains(first, 5);
cout << r1 << " " << r2 << endl;
return 0;
}
I expect this to print 0 1 but result is 1 1
Beginner c++ labmda programmer here so sorry in advance if this is a basic error.
Don't capture a by reference, capture it by value. As-is, you're storing a dangling reference inside the lambda, and using it later leads to UB.
set singletonSet(int a) {
return [=] (int x) { return (a == x); };
// ^
}
Creating a functor requires an unnecessary boiler plate. The state has to be written 4 times!
struct f{
double s; // 1st
f(double state): s(state) {} // 2nd, 3rd and 4th
double operator() (double x) {
return x*s;
}
};
is there a library with a macro that would be just double functor(state)(x){ return x*state; } or something similar.
BOOST_FOREACH is a macro adapter that works well. I'm looking for something similar.
any suggestions on how to write one is appreciated too.
ps. using struct for functor is faster then bind Class's operator() or bind a function as a functor?
Update(1)
in regards to lambdas:
the functor has to be modular, meaning, it should be reusable in other function. lambdas have to be within a function -- lambda has to be in main to be called from main and other functions outside of main, can't call the lambda defined in main.
How about relying on aggregate initialization? Simply do not declare the constructor:
struct f {
double s;
double operator()(double x) {
return x * s;
}
};
use it like this
int main()
{
auto ff = f{42};
std::cout << ff(2);
return 0;
}
Define the functionality you want, e.g., you multiplication, as a function and then use std::bind() to create a suitable function object:
#include <functional>
double some_operation(double state, double x) {
return state * x;
}
int main() {
auto function = std::bind(&some_operation, 17, std::placeholders::_1);
return function(18);
}
Since a call through a function pointer generally can't be inlined, you might want to write your function as a function object instead:
#include <functional>
struct some_operation {
double operator()(double state, double x) const {
return state * x;
}
};
int main() {
auto function = std::bind(some_operation(), 17, std::placeholders::_1);
return function(18);
}
Below is a test program which seems to indicate that the speed of a hand-crafted function object and a bound function object are about the same, i.e., the results I get are
in 90 ms, functor as a struct; result = 1.5708e+16
in 262 ms, function pointer through bind; result = 1.5708e+16
in 261 ms, function through bind; result = 1.5708e+16
in 87 ms, function object through bind; result = 1.5708e+16
in 88 ms, non-called bind with function; result = 1.5708e+16
in 88 ms, non-called bind with function pointer; result = 1.5708e+16
using a recent version of clang (more precisely: clang version 3.4 (trunk 182411)) on a MacOS system optimizing with -O2 option. Using and gcc (more precisely: gcc version 4.9.0 20130811 (experimental) (GCC)) gives similar results.
It seems it makes a difference whether the function object is build in the local context or passed via template argument to a separate function. This difference is interesting as I would expect that most of the uses of bind() a function will result in passing off the resulting function object somewhere.
The code is based on https://stackoverflow.com/a/18175033/1120273:
#include <iostream>
#include <functional>
#include <chrono>
using namespace std;
using namespace std::placeholders;
using namespace std::chrono;
struct fs {
double s;
fs(double state) : s(state) {}
double operator()(double x) {
return x*s;
}
};
struct ff {
double operator()(double x, double state) const {
return x * state;
}
};
double fb(double x, double state) {
return x*state;
}
template <typename Function>
void measure(char const* what, Function function)
{
const auto stp1 = high_resolution_clock::now();
double sresult(0.0);
for(double x=0.0; x< 1.0e8; ++x) {
sresult += function(x);
}
const auto stp2 = high_resolution_clock::now();
const auto sd = duration_cast<milliseconds>(stp2 - stp1);
cout << "in " << sd.count() << " ms, ";
cout << what << "; result = " << sresult << endl;
}
int main() {
double state=3.1415926;
measure("functor as a struct", fs(state));
measure("function through bind", std::bind(&fb, _1, state));
measure("function object through bind", std::bind(ff(), _1, state));
{
const auto stp1 = high_resolution_clock::now();
double sresult(0.0);
auto function = std::bind(fb, _1, state);
for(double x=0.0; x< 1.0e8; ++x) {
sresult += function(x);
}
const auto stp2 = high_resolution_clock::now();
const auto sd = duration_cast<milliseconds>(stp2 - stp1);
cout << "in " << sd.count() << " ms, ";
cout << "embedded bind with function; result = " << sresult << endl;
}
{
const auto stp1 = high_resolution_clock::now();
double sresult(0.0);
auto function = std::bind(&fb, _1, state);
for(double x=0.0; x< 1.0e8; ++x) {
sresult += function(x);
}
const auto stp2 = high_resolution_clock::now();
const auto sd = duration_cast<milliseconds>(stp2 - stp1);
cout << "in " << sd.count() << " ms, ";
cout << "embedded bind with function pointer; result = " << sresult << endl;
}
return 0;
}
We've got lambdas for this:
double s = 42;
auto f = [s](double x) {
return s * x;
};
Down to single mention of state on line 2 (as you dont seem to count one in the actual expression). Whether initialization on line 1 counts as mention is debatable, your desired form does not contain any initialization, which is required, so I assume this to be acceptable.
In c++14 we'll get extension of lambda capture syntax allowing even more terse form:
auto f = [s{42}](double x) {
return s * x;
};
Have a look at BOOST_LOCAL_FUNCTION which seems to be exactly what youre looking for, as you even mention a macro :)
double s = 42;
double BOOST_LOCAL_FUNCTION(bind& s, double x) {
return x*s;
} BOOST_LOCAL_FUNCTION_NAME(f)
Personal note: If you have a modern compiler, go with C++11 lambdas.