std::result_of parameter type - c++

I've been having this question for some time. Suppose we have a contrived function:
template<typename F>
std::result_of_t<std::decay_t<F>(???)> transform(F&& f)
{
static const int num = 42;
return std::forward<F>(f)(num);
}
The thing I'm not sure of is whether I should use int or const int& for the ??? part. Similarly, for this function:
template<typename F>
std::result_of_t<std::decay_t<F>(???)> transform(F&& f)
{
ExpensiveType foo;
return std::forward<F>(f)(std::move(foo));
}
Should I use ExpensiveType or ExpensiveType&& for the ??? part?

Use auto!
C++14:
template < typename F >
auto transform(F&& f)
{
constexpr auto num = 42;
return std::forward<F>(f)(num);
}
C++11:
template < typename F >
auto transform(F&& f) -> decltype(std::forward<F>(f)(42))
{
// ... same body
}

Related

How to make a function that accepts another one with argument tuple

I need a function My_func that works like this
auto f = [](const std::tuple<string, double>& t) { return std::get<0>(t); };
assert(My_func(f)("Hello", 8.5) == f({"Hello", 8.5}));
Now i have
template <class F>
constexpr auto My_func(F&& f) {
return [f](auto&& args...) { return std::forward<F>(f)(args); };
}
But it doesn't work.What should i fix?
First of all you need My_func to be syntactically valid. You have a pack args that is not expanded in the lambda. Then you need to mention tuple somewhere. C++ is not psychic.
Luckily, there exists std::forward_as_tuple that does exactly what you need here
template <class F>
constexpr auto My_func(F&& f) {
return [f = std::forward<F>(f)](auto&& args...) { return f(std::forward_as_tuple(args...)); };
}
template <class F>
constexpr auto My_func(F&& f)
{
return [f = std::forward<F>(f)](auto&&... args) {
return f(std::make_tuple(std::forward<decltype(args)>(args)...));
};
}

Enabling automatic deduction of template argument type based on that argument's default value

Here's what I want to do:
#include <vector>
template <class ContainerType, typename ComparatorType>
void f(
ContainerType c1,
ComparatorType comp =
[](const typename ContainerType::value_type& l, const typename ContainerType::value_type& r) {return l < r;})
{
}
int main()
{
std::vector<int> a{1, 2};
f(a);
return 0;
}
But it doesn't work: could not deduce template argument for 'ComparatorType'.
Using a proxy function instead of an actual default argument value works, but seems overly verbose, isn't there a better way? Not to mention it's not the same since now I can't just substitute the default comparator with my own without changing the function name in the client code.
#include <vector>
template <class ContainerType, typename ComparatorType>
void f(
ContainerType c1,
ComparatorType comp)
{
}
template <class ContainerType>
void f2(ContainerType c)
{
f(c, [](const typename ContainerType::value_type& l, const typename ContainerType::value_type& r) {return l < r;});
}
int main()
{
std::vector<int> a{1, 2};
f2(a);
return 0;
}
without changing the function name in the client code.
You can overload function templates just fine. There is no need to use a different name.
template <class ContainerType, typename ComparatorType>
void f(
ContainerType c1,
ComparatorType comp)
{
}
template <class ContainerType>
void f(ContainerType c)
{
f(c, [](const typename ContainerType::value_type& l, const typename ContainerType::value_type& r) {return l < r;});
}
You can't make a default function argument contribute to template argument deduction. It's not allowed because it raises some difficult to resolve questions in the deduction process.
Template deduction is performed before default arguments are considered. Also, lambdas are not allowed to appear in unevaluated operands.
You can first assign the default function to a variable. Then you can spell out its type. For example:
auto default_functor = [](int x){ return x > 0; };
template <typename T, typename F = decltype(default_functor)>
auto function(T x, F f = default_functor)
{
return f(x);
}
Now you can use the function as usual:
bool even(int x)
{
return x % 2 == 0;
}
struct Odd {
bool operator()(int x) const
{
return x % 2 == 1;
}
};
void g()
{
function(1); // use default functor
function(1, even); // use a free function
function(1, Odd{}); // use a function object
function(1, [](int x){ return x < 0; }); // use another lambda
}
You don't need to explicitly specify the type.
Note: According to #StoryTeller, this can lead to ODR violation if you use it in a header. In that case, you can use a named functor type:
struct Positive {
constexpr bool operator(int x) const
{
return x > 0;
}
};
inline constexpr Positive default_functor{};
template <typename T, typename F = decltype(default_functor)>
auto function(T x, F f = default_functor)
{
return f(x);
}

Wrapping a templated function call in a lambda

I am trying to write code to do something similar (code written for demonstration purposes) to this:
template <typename F, typename Args...>
inline auto runFunc(F func) -> foo
{
return foo([func](Args... args) -> std::result_of<F>::type
{
// Do something before calling func
func(args...);
// Do something after call func
});
}
So basically I am trying to write a function that returns an object that takes lambda that matches the templated function type. Obviously this code won't work because I do not have Args... defined. How would I solve this in C++11?
template<class F_before, class F, class F_after>
struct decorate_func_t {
F_before f0;
F f1;
F_after f2;
template<class...Args>
typename std::result_of<F(Args...)>::type operator()(Args&&...args)const{
f0();
auto r = f1(std::forward<Args>(args)...);
f2();
return r;
}
};
template<class F_before, class F, class F_after>
decorate_func_t<F_before, F, F_after>
decorate_func( F_before before, F f, F_after after ){
return {std::move(before), std::move(f), std::move(after)};
}
Then:
template <typename F, typename Args...>
inline auto runFunc(F func) -> foo
{
return foo(decorate_func(
[]{/* Do something before calling func */},
func,
[]{/* Do something after call func */ }
};
}
the lack of auto parameters in C++11 lambdas makes this about the best you can do.
In C++14 this is trivial:
template <class F>
auto runFunc(F func)
{
return foo(
[func](auto&&... args) // ->decltype(auto) maybe
{
// Do something before calling func
auto r = func(decltype(args)(args)...);
// Do something after call func
return r;
}
);
}
note that many nominally C++11 compilers actually support auto parameters on lambdas.
You can use a support structure as in the following example:
#include<type_traits>
#include<cassert>
struct foo {
template<typename F>
foo(F f) { assert(42 == f(42)); }
};
template<typename>
struct S;
template<typename R, typename... Args>
struct S<R(*)(Args...)> {
template <typename F>
static auto runFunc(F func) -> foo
{
return foo{[func](Args... args) -> R
{
// Do something before calling func
auto r = func(args...);
// Do something after call func
return r;
}};
}
};
template<typename F>
inline auto runFunc(F func) -> foo
{
return S<F>::runFunc(func);
}
int f(int i) { return i; }
int main() {
runFunc(f);
}
For it's not clear to me what's the context of the problem, I'm not sure I got exactly what you were asking for.
I hope the code above can help you.
Still being unsure it this is what you're searching for, I risk posting:
#include <iostream>
struct foo
{
template<typename T>
foo(T lambda)
{
lambda(1, 2);
}
};
template <typename F, typename... Args>
inline typename std::result_of<F>::type runFunc(F func)
{
return foo(
[func](Args... args)
{
std::cout << "Before";
func(args...);
std::cout << "After";
}
);
}
struct print
{
void operator()(int i) const
{
std::cout << i << std::endl;
}
void operator()(int i, int j) const
{
std::cout << i << " " << j << std::endl;
}
};
int main()
{
runFunc<print, int, int>(print());
}

Shortcut syntax for boost function_input_iterator range

I am wondering if there is a shortcut syntax for this sort of code:
#include <boost/iterator/function_input_iterator.hpp>
#include <boost/range.hpp>
int main() {
std::function<int (int)> f = [](int i) -> int {
// some logic, return int
};
auto r = boost::make_iterator_range(boost::make_function_input_iterator(f, 0), boost::make_function_input_iterator(f, 10));
return 0;
}
Two notes:
I couldn't use auto f = [](int i) ->int {...}; as this causes:
error: no type named 'result_type' in 'struct main()::<lambda(int)>'
using std::function fixes it for some reason.
Also I can't pass f as temporary inline ie boost::make_function_input_iterator([](int i) ->int {...}, ... as that function takes f by reference.
Ideally I'd like to be able to do:
make_function_input_range(0, 10, [](int i)->int {...});
You could use a trivial wrapper that adds the typedef:
template <typename F>
struct ref_wrap : std::reference_wrapper<F> {
typedef decltype(std::declval<F>()() result_type;
ref_wrap(F& f) : std::reference_wrapper<F>(f) {}
};
PS. I use a reference wrapper to stay with function_input_iterator's requirements, which already require the function to be an lvalue reference. You could leave this behind now, actually, since we return the function wrapper as well as the range, see below
Next up, have a helper that returns a tuple of that wrapper and the iterator-range built on it:
template <typename F>
struct input_function_range_wrapper {
struct ref_wrap : std::reference_wrapper<F> {
typedef decltype(std::declval<F>()()) result_type;
ref_wrap(F& f) : std::reference_wrapper<F>(f) {}
} wrap;
using It = boost::function_input_iterator<ref_wrap, int>;
boost::iterator_range<It> range;
template <typename V>
input_function_range_wrapper(F& f, V a, V b) : wrap(f), range(It(wrap, a), It(wrap, b))
{ }
};
To make using it convenient, lets move it into a detail namespace and add a factory function:
template <typename F, typename V = int>
auto make_input_function_range(F& f, V a, V b) {
return detail::input_function_range_wrapper<F>(f, a, b);
}
Now to really top it off, we add ADL-enabled begin and end calls and PRONTO, we can use c++'s ranged-for on it:
int main() {
auto f = [i=1]() mutable { return i*=2; };
for (auto v : make_input_function_range(f, 0, 10)) {
std::cout << v << " ";
}
}
Prints
2 4 8 16 32 64 128 256 512 1024
FULL DEMO
Live On Coliru
#include <boost/iterator/function_input_iterator.hpp>
#include <boost/range.hpp>
namespace detail {
template <typename F>
struct input_function_range_wrapper {
struct ref_wrap : std::reference_wrapper<F> {
typedef decltype(std::declval<F>()(/*std::declval<V>()*/)) result_type;
ref_wrap(F& f) : std::reference_wrapper<F>(f) {}
} wrap;
using It = boost::function_input_iterator<ref_wrap, int>;
boost::iterator_range<It> range;
template <typename V>
input_function_range_wrapper(F& f, V a, V b) : wrap(f), range(It(wrap, a), It(wrap, b))
{ }
};
template <typename... Ts>
auto begin(input_function_range_wrapper<Ts...>& r) { return r.range.begin(); }
template <typename ... Ts>
auto begin(input_function_range_wrapper<Ts...> const& r) { return r.range.begin(); }
template <typename ... Ts>
auto end (input_function_range_wrapper<Ts...>& r) { return r.range.end (); }
template <typename ... Ts>
auto end (input_function_range_wrapper<Ts...> const& r) { return r.range.end (); }
}
template <typename F, typename V = int>
auto make_input_function_range(F& f, V a, V b) {
return detail::input_function_range_wrapper<F>(f, a, b);
}
#include <iostream>
int main() {
auto f = [i=1]() mutable { return i*=2; };
for (auto v : make_input_function_range(f, 0, 10)) {
std::cout << v << " ";
}
}
For the error: no type named 'result_type', refer to this bug.
make_function_input_range is trivial to write, but this cannot be used with plain lambdas, because of the mentioned bug:
template<class T>
auto make_function_input_range(std::size_t begin, std::size_t end, T& f) {
return boost::make_iterator_range(
boost::make_function_input_iterator(f, begin),
boost::make_function_input_iterator(f, end));
}
To work around the bug, I would create a small helper type that defines the required result_type, rather than use the type-erasing std::function:
template<class T>
struct fun_wrapper {
T f;
using result_type = typename boost::function_types::result_type<T>;
template<class... Args>
result_type operator() (Args&&... args) const {
return f(std::forward<Args>(args)...);
}
};
template<class T>
auto make_fun_wrapper(T&& f) {
return fun_wrapper<T>{std::forward<T>(f)};
}
int main() {
auto wrapped_f = make_fun_wrapper([](int i)->int {/*...*/});
auto range = make_function_input_range(0, 10, wrapped_f);
}

function composition in C++ / C++11

I am currently coding some cryptographic algorithms in C++11 that require a lot of function compositions. There are 2 types of composition I have to deal with :
Compose a function on itself a variable number of times. Mathematically, for a certain function F, F^n(x) = (F^{n-1} o F)(x) = F^{n-1}(F(x)).
Compose different functions together. For example, for some functions f,g,h,i,j and k of the same type, I'll have f(g(h(i(j(k(x)))))).
In my case, I'm using the following definition of F :
const std::vector<uint8_t> F(const std::vector<uint8_t> &x);
I would like to compose this function on itself n times. I have implemented the composition in a simple recursive way which is working fine :
const std::vector<uint8_t> compose(const uint8_t n, const std::vector<uint8_t> &x)
{
if(n > 1)
return compose(n-1, F(x));
return F(x);
}
For this case, is there a more efficient way an proper way to implement this composition using c++11 but without using BOOST ?
It would be great to use this form if it is possible of course :
answer = compose<4>(F)(x); // Same as 'answer = F^4(x) = F(F(F(F(x))))'
For the second case, I would like to implement the composition of a variable number of functions. For a given set of functions F0, F1, ..., Fn having the same definition as F, is there an efficient and proper way to compose them where n is variable ?
I think variadic template would be useful here, but I don't know how to use them in that case.
Thanks for your help.
Something along these lines, perhaps (untested):
template <typename F>
class Composer {
int n_;
F f_;
public:
Composer(int n, F f) : n_(n), f_(f) {}
template <typename T>
T operator()(T x) const {
int n = n_;
while (n--) {
x = f_(x);
}
return x;
}
};
template <int N, typename F>
Composer<F> compose(F f) {
return Composer<F>(N, f);
}
EDIT: And for the second case (tested this time):
#include <iostream>
template <typename F0, typename... F>
class Composer2 {
F0 f0_;
Composer2<F...> tail_;
public:
Composer2(F0 f0, F... f) : f0_(f0), tail_(f...) {}
template <typename T>
T operator() (const T& x) const {
return f0_(tail_(x));
}
};
template <typename F>
class Composer2<F> {
F f_;
public:
Composer2(F f) : f_(f) {}
template <typename T>
T operator() (const T& x) const {
return f_(x);
}
};
template <typename... F>
Composer2<F...> compose2(F... f) {
return Composer2<F...>(f...);
}
int f(int x) { return x + 1; }
int g(int x) { return x * 2; }
int h(int x) { return x - 1; }
int main() {
std::cout << compose2(f, g, h)(42);
return 0;
}
Thanks for the fun question, Gabriel of year 2013.
Here is a solution. It works in c++14.
#include <functional>
#include <iostream>
using std::function;
// binary function composition for arbitrary types
template <class F, class G> auto compose(F f, G g) {
return [f, g](auto x) { return f(g(x)); };
}
// for convienience
template <class F, class G> auto operator*(F f, G g) { return compose(f, g); }
// composition for n arguments
template <class F, typename... Fs> auto compose(F f, Fs &&... fs) {
return f * compose(fs...);
}
// composition for n copies of f
template <int i, class F>
// must wrap chain in a struct to allow partial template specialization
struct multi {
static F chain(F f) { return f * multi<i - 1, F>::chain(f); }
};
template <class F> struct multi<2, F> {
static F chain(F f) { return f * f; }
};
template <int i, class F> F compose(F f) { return multi<i, F>::chain(f); }
int main(int argc, char const *argv[]) {
function<double(int)> f = [](auto i) { return i + 3; };
function<int(double)> g = [](auto i) { return i * 2; };
function<int(int)> h = [](auto i) { return i + 1; };
std::cout << '\n'
<< "9 == " << compose(f, g, f)(0) << '\n'
<< "5 == " << (f * g * h)(0) << '\n'
<< "100 == " << compose<100>(h)(0) << '\n';
return 0;
}
You can define
Matrix compose(Matrix f, Matrix g);
or
Rotation compose(Rotation f, Rotation g);
to reuse this code for all sorts of things.
A very general example (g++ -std=c++1y composition.cpp):
// ---------------------------------------------------------
// "test" part
// ---------------------------------------------------------
int f(int a) { return 2*a; }
double g(int a) { return a+2.5; }
double h(double a) { return 2.5*a; }
double i(double a) { return 2.5-a; }
class Functor {
double x;
public:
Functor (double x_) : x(x_) { }
double operator() (double a) { return a*x; }
};
// ---------------------------------------------------------
// ---------------------------------------------------------
int main () {
auto l1 = [] (double a) { return a/3; };
auto l2 = [] (double a) { return 3.5+a; };
Functor fu {4.5};
auto compos1 = compose (f, g, l1, g, h, h, l1, l2);
auto compos2 = compose (compos1, l1, l2, fu);
auto x = compos2 (3);
cout << x << endl;
cout << compos2(3) << endl;
cout << fu(l2(l1(l2(l1(h(h(g(l1(g(f(3))))))))))) << endl;
} // ()
Library part:
// ---------------------------------------------------------
// "library" part
// ---------------------------------------------------------
template<typename F1, typename F2>
class Composite{
private:
F1 f1;
F2 f2;
public:
Composite(F1 f1, F2 f2) : f1(f1), f2(f2) { }
template<typename IN>
decltype(auto) operator() (IN i)
{
return f2 ( f1(i) );
}
};
// ---------------------------------------------------------
// ---------------------------------------------------------
template<typename F1, typename F2>
decltype(auto) compose (F1 f, F2 g) {
return Composite<F1, F2> {f,g};
}
// ---------------------------------------------------------
// ---------------------------------------------------------
template<typename F1, typename... Fs>
decltype(auto) compose (F1 f, Fs ... args)
{
return compose (f, compose(args...));
}
The whole program:
// g++ -std=c++1y composition.cpp
#include <iostream>
using namespace std;
// ---------------------------------------------------------
// "library" part
// ---------------------------------------------------------
template<typename F1, typename F2>
class Composite{
private:
F1 f1;
F2 f2;
public:
Composite(F1 f1, F2 f2) : f1(f1), f2(f2) { }
template<typename IN>
decltype(auto) operator() (IN i)
{
return f2 ( f1(i) );
}
};
// ---------------------------------------------------------
// ---------------------------------------------------------
template<typename F1, typename F2>
decltype(auto) compose (F1 f, F2 g) {
return Composite<F1, F2> {f,g};
}
// ---------------------------------------------------------
// ---------------------------------------------------------
template<typename F1, typename... Fs>
decltype(auto) compose (F1 f, Fs ... args)
{
return compose (f, compose(args...));
}
// ---------------------------------------------------------
// "test" part
// ---------------------------------------------------------
int f(int a) { return 2*a; }
double g(int a) { return a+2.5; }
double h(double a) { return 2.5*a; }
double i(double a) { return 2.5-a; }
class Functor {
double x;
public:
Functor (double x_) : x(x_) { }
double operator() (double a) { return a*x; }
};
// ---------------------------------------------------------
// ---------------------------------------------------------
int main () {
auto l1 = [] (double a) { return a/3; };
auto l2 = [] (double a) { return 3.5+a; };
Functor fu {4.5};
auto compos1 = compose (f, g, l1, g, h, h, l1, l2);
auto compos2 = compose (compos1, l1, l2, fu);
auto x = compos2 (3);
cout << x << endl;
cout << compos2(3) << endl;
cout << fu(l2(l1(l2(l1(h(h(g(l1(g(f(3))))))))))) << endl;
} // ()
Here is a simple c++14 solution (it may probably be re-written to c++11):
#include <iostream>
// base condition
template <typename F>
auto compose(F&& f)
{
return [a = std::move(f)](auto&&... args){
return a(std::move(args)...);
};
}
// recursive composition
// from compose(a, b, c...) to compose(ab, c...)
template <typename F1, typename F2, typename... Fs>
auto compose(F1&& f1, F2&& f2, Fs&&... fs)
{
return compose(
[first = std::move(f1), second = std::move(f2)]
(auto&&... args){
return second(first(std::move(args)...));
},
std::move(fs)...
);
}
Possible usage:
int main()
{
const auto f = compose(
[](const auto n){return n * n;},
[](const auto n){return n + 2;},
[](const auto n){return n + 2;}
);
std::cout << f(10) << std::endl; // outputs 104
}
Here is a link to the repo with a few more examples: https://github.com/nestoroprysk/FunctionComposition
A quick implementation of function iteration with argument forwarding. The helper type is unfortunately necessary because function templates can’t be partially specialised.
#include <functional>
#include <iostream>
using namespace std;
template<int n, typename A>
struct iterate_helper {
function<A(A)> f;
iterate_helper(function<A(A)> f) : f(f) {}
A operator()(A&& x) {
return f(iterate_helper<n - 1, A>(f)(forward<A>(x)));
};
};
template<typename A>
struct iterate_helper<1, A> {
function<A(A)> f;
iterate_helper(function<A(A)> f) : f(f) {}
A operator()(A&& x) {
return f(forward<A>(x));
};
};
template<int n, typename A>
function<A(A)> iterate(function<A(A)> f) {
return iterate_helper<n, A>(f);
}
int succ(int x) {
return x + 1;
}
int main() {
auto add5 = iterate<5>(function<int(int)>(succ));
cout << add5(10) << '\n';
}
You haven't shown the body of F, but if you can modify it so that it mutates the input to form the output then change the signature to:
void F(std::vector<uint8_t>& x);
Thereafter you can implement Fn as:
void Fn(std::vector<uint8_t>& x, size_t n)
{
for (size_t i = 0; i < n; i++)
F(x);
}
The compiler will unroll the loop for you if it is more efficient, but even if it doesn't an increment/compare of a local variable will be orders of magnitude faster than calling F.
You can then explcitly copy-construct new vectors when you actually want to make a copy:
vector<uint8_t> v1 = ...;
vector<uint8_t> v2 = v1; // explicitly take copy
Fn(v2,10);
What about (untested):
template < typename Func, typename T >
T compose_impl( Func &&, T &&x, std::integral_constant<std::size_t, 0> )
{ return std::forward<T>(x); }
template < typename Func, typename T, std::size_t N >
T compose_impl( Func &&f, T &&x, std::integral_constant<std::size_t, N> )
{
return compose_impl( std::forward<Func>(f),
std::forward<Func>(f)(std::forward<T>( x )),
std::integral_constant<std::size_t, N-1>{} );
}
template < std::size_t Repeat = 1, typename Func, typename T >
T compose( Func &&f, T &&x )
{
return compose_impl( std::forward<Func>(f), std::forward<T>(x),
std::integral_constant<std::size_t, Repeat>{} );
}
We can use variadic function templates for multiple functions (untested):
template < typename Func, typename T >
constexpr // C++14 only, due to std::forward not being constexpr in C++11
auto chain_compose( Func &&f, T &&x )
noexcept( noexcept(std::forward<Func>( f )( std::forward<T>(x) )) )
-> decltype( std::forward<Func>(f)(std::forward<T>( x )) )
{ return std::forward<Func>(f)(std::forward<T>( x )); }
template < typename Func1, typename Func2, typename Func3, typename ...RestAndT >
constexpr // C++14 only, due to std::forward
auto chain_compose( Func1 &&f, Func2 &&g, Func3 &&h, RestAndT &&...i_and_x )
noexcept( CanAutoWorkHereOtherwiseDoItYourself )
-> decltype( auto ) // C++14 only
{
return chain_compose( std::forward<Func1>(f),
chain_compose(std::forward<Func2>( g ), std::forward<Func3>( h ),
std::forward<RestAndT>( i_and_x )...) );
}
The upcoming decltype(auto) construct automatically computes the return type from an inlined function. I don't know if there's a similar automatic computation for noexcept