Can I create an integral_constant from a loop variable? - c++

I try to extract all single blocks from a block matrix. However the BlockMatrixClass from the library I am using only allows access through the following indices:
Dune::index_constant<0>(), Dune::index_constant<1>(),...
They resolve to std::integral_constant<long unsigned int, 0>().
How I can alter the following code to be valid? Without changing the library.
for(std::size_t i=0; i<3; i++){
for(std::size_t j=0; j<3; j++){
const auto& m = jacobian[Dune::index_constant<i>()][Dune::index_constant<j>()];
}
}
At the moment I get the error
error: the value of ‘j’ is not usable in a constant expression
401 | t auto& m = jacobian[Dune::index_constant<i>()][Dune::index_constant<j>()];

Iterating over a compile time sequence is not a completely solved problem since they all rely on various workaround and there is many ways to do it.
My preferred way is to use an index sequence, and unroll it using fold expressions:
Simply define this:
template<typename T, T... S, typename F>
constexpr void for_sequence(std::integer_sequence<T, S...>, F&& f) {
(static_cast<void>(f(std::integral_constant<T, S>{})), ...);
}
Then, use it like that:
for_sequence(std::make_index_sequence<3>{}, [&](auto i) {
for_sequence(std::make_index_sequence<3>{}, [&](auto j) {
const auto& m = jacobian[Dune::index_constant<i>()][Dune::index_constant<j>()];
});
});
The variable i and j here are integral constants and can be used in template parameters. The actual std::integer_sequence you send to the function dictate with what value to instantiate the innermost lambda.
If jacobian can use those integral constant directly instead of their own Dune::index_constant, you can simply write this:
for_sequence(std::make_index_sequence<3>{}, [&](auto i) {
for_sequence(std::make_index_sequence<3>{}, [&](auto j) {
const auto& m = jacobian[i][j];
});
});

#include <cstdint>
#include <cstddef>
#include <utility>
template <size_t index, size_t end>
void for_loop () {
if constexpr (index == end) {
return;
}
constexpr size_t i = index / 3;
constexpr size_t j = index % 3;
const auto& m = jacobian[Dune::index_constant<i>()][Dune::index_constant<j>()];
impl<index + 1, end>();
}
template <size_t end>
void for_loop_to() {
for_loop<0, end>();
}
int main ()
{
for_loop_to<9>();
}
Would something like this work for a constexpr for loop type thing? This works for C++17 (since it requires the constexpr if) but more verbose versions would be implemented for earlier c++ versions. Also I didn't plumb jacobian through to the inner function, but you could do that with a struct wrapper.

You can unroll the loops:
const auto& m = jacobian[Dune::index_constant<0>()][Dune::index_constant<0>()];
const auto& m = jacobian[Dune::index_constant<0>()][Dune::index_constant<1>()];
const auto& m = jacobian[Dune::index_constant<0>()][Dune::index_constant<2>()];
const auto& m = jacobian[Dune::index_constant<1>()][Dune::index_constant<0>()];
const auto& m = jacobian[Dune::index_constant<1>()][Dune::index_constant<1>()];
const auto& m = jacobian[Dune::index_constant<1>()][Dune::index_constant<2>()];
const auto& m = jacobian[Dune::index_constant<2>()][Dune::index_constant<0>()];
const auto& m = jacobian[Dune::index_constant<2>()][Dune::index_constant<1>()];
const auto& m = jacobian[Dune::index_constant<2>()][Dune::index_constant<2>()];
If thats not an option you can apply some form of compile time for:
#include <utility>
#include <iostream>
template <template<size_t> class F,size_t ... I>
void for_impl(std::index_sequence<I...>){
(F<I>{}(),...);
}
template <template<size_t> class F,std::size_t N,typename Indices = std::make_index_sequence<N>>
void for_(){
for_impl<F>(Indices{});
}
template <size_t i>
struct foo{
void operator()() {
std::cout << i << "\n";
}
};
int main() {
for_<foo,5>();
}
Here only outlined for one loop. I wasn't sure if you need both loops unrolled at compile time. In the example foo is the template you would wrap the loop body inside.

Related

Alias a std::min and std::max functions

I'm trying to create aliases for std::min and std::max functions based on this answer, but if I try the following code:
#include <algorithm>
namespace math
{
template< typename T >
constexpr auto Max = std::max< T >;
}
and try to run such example:
constexpr int a = 2;
constexpr int b = 3;
constexpr int max = math::Max( a, b );
I get this error:
error C3245: 'math::Max': use of a variable template requires template argument list
What is the best way in modern C++ to do this correctly?
Perhaps this bleeding-edge-modern, law-abiding, namespace-respecting, argument-forwarding function alias construct can work for you.
#define FUNCTION_ALIAS(from, to) \
decltype(auto) to(auto&& ... xs) \
{ return from(std::forward<decltype(xs)>(xs)...); }
FUNCTION_ALIAS(std::max, Max)
One possible solution is to introduce a function object:
struct Max_ {
template<class T>
constexpr T operator()(const T& a, const T& b) const {
return std::max(a, b);
}
};
inline constexpr Max_ Max = {};
Then you can do
std::cout << Max(4, 5); // prints 5

Default constructing an std::variant from index

What's the easiest way to default construct an std::variant from the index of the desired type, when the index is only known at runtime? In other words, I want to write:
const auto indx = std::variant<types...>{someobject}.index();
//...somewhere later, indx having been passed around...
std::variant<types...> var = variant_from_index(indx);
///var is now set to contain a default constructed someobject
Note that indx cannot be made constexpr, so std::in_place_index doesn't work here.
The problem here is of course that since it isn't known which constructor from types... to call at compile time, somehow basically a table of all possible constructors (or maybe default constructed variants to copy from) has to be built at compile time and then accessed at run time. Some template magic is apparently in place here, but what would be the cleanest way?
I tried the following (on coliru), but the index sequence seems to come out wrong (the print in the end gives 2 0 0), and I'm confused as to why:
Edit: it works as fixed below, I had the constexpr array initialization wrong. So the question is now, is there a neater way to do this?
#include <variant>
#include <iostream>
using var_t = std::variant<int, float, const char *>;
//For debug
template<class ...types>
struct WhichType;
template<class T, class U>
struct default_variants;
template<class...Params, std::size_t... I>
struct default_variants<std::variant<Params...>, std::index_sequence<I...>> {
using variant_t = std::variant<Params...>;
//Uncomment to see the index sequence
//WhichType<std::index_sequence<I...>> idx{};
constexpr static variant_t variants[sizeof...(Params)]{variant_t{std::in_place_index<I>}...};
constexpr static std::size_t indices[sizeof...(Params)]{I...};
};
template<class T>
struct default_variants_builder;
template<class...Params>
struct default_variants_builder<std::variant<Params...>> {
using indices = std::make_index_sequence<sizeof...(Params)>;
using type = default_variants<std::variant<Params...>, indices>;
};
int main() {
using builder_t = typename default_variants_builder<var_t>::type;
var_t floatvar{1.2f};
var_t variant2 = builder_t::variants[floatvar.index()];
std::cout << "Contained " << floatvar.index() << "; Now contains " << variant2.index() << "\n";
}
With Boost.Mp11 this is basically a one-liner (as always):
template <typename V>
auto variant_from_index(size_t index) -> V
{
return mp_with_index<mp_size<V>>(index,
[](auto I){ return V(std::in_place_index<I>); });
}
Your description of the problem is accurate - you need a way to turn a runtime index into a compile-time index. mp_with_index does that for you - you give it the runtime index and the maximum compile-time index (mp_size<V> here, which would give the same value as std::variant_size_v<V> if you prefer that instead) and it will invoke a function you provide with the correct constant (I has type integral_constant<size_t, index> here, except with index being a constant expression).
How about this?
template <class Variant, std::size_t I = 0>
Variant variant_from_index(std::size_t index) {
if constexpr(I >= std::variant_size_v<Variant>)
throw std::runtime_error{"Variant index " + std::to_string(I + index) + " out of bounds"};
else
return index == 0
? Variant{std::in_place_index<I>}
: variant_from_index<Variant, I + 1>(index - 1);
}
See it live on Wandbox
Not sure if this is very elegant or not but I think it works:
#include <variant>
#include <iostream>
template<typename V, std::size_t N = std::variant_size_v<V>>
struct variant_by_index {
V make_default(std::size_t i) {
if (i >= std::variant_size_v<V>) {
throw std::invalid_argument("bad type index.");
}
constexpr size_t index = std::variant_size_v<V> - N;
if (i == index) {
return std::variant_alternative_t<index, V>();
} else {
return variant_by_index<V, N - 1>().make_default(i);
}
}
};
template<typename V>
struct variant_by_index<V, 0> {
V make_default(std::size_t i) {
throw std::bad_variant_access("bad type index.");
}
};
using var_t = std::variant<int, float, const char *>;
int main() {
variant_by_index<var_t> type_indexer;
var_t my_var_0 = type_indexer.make_default(0);
std::cout << "my_var_0 has int? " << std::holds_alternative<int>(my_var_0) << "\n";
var_t my_var_1 = type_indexer.make_default(1);
std::cout << "my_var_1 has float? " << std::holds_alternative<float>(my_var_1) << "\n";
try {
var_t my_var_1 = type_indexer.make_default(3);
} catch(const std::bad_variant_access&) {
std::cout << "Could not create with type 3.\n";
}
return 0;
}
I believe a (somewhat) elegant way might be using a more general idiom for choosing a numeric template parameter value at run time, as discussed in this question:
Idiom for simulating run-time numeric template parameters?
The foo function there will be std::get<std::size_t I> (or a lambda which captures the variant and takes no arguments).

Is it possible to set the value of elements in a constexpr array after declaration?

Is it possible to declare a const array (possibly constexpr) at one point, then define it at another place, one element at a time?
E.g.
extern constexpr int myArray[100];
myArray[0] = myConstexprFunction(0);
myArray[1] = myConstexprFunction(1);
// ...
myArray[100] = myConstexprFunction(100);
What I'm trying to do will need something like this. Maybe it's possible using things like: http://b.atch.se/posts/constexpr-counter/
But if this technique is going to be illegal in the next C++ standard (I hope not) I would like to use a safer one.
[EDIT] how about relaxing some requirements.. let's say that I want to do something like this:
constexpr int myConstExprFunction(int arg) { return arg + 100;}
// other code...
constexpr int a = myConstExprFunctionBegin(10);
constexpr int b = myConstExprFunction(20);
constexpr int c = myConstExprFunction(30);
constexpr int d = myConstExprFunctionEnd(40);
what I would like to have is that the myConstExprFunctionEnd is able to generate a final array with the values created by the previous functions.
Everything at compile time of course.
[EDIT2] C++11 solutions very welcomed
The requirement of constexpr of the recent C++ is very relaxed, so you could just write:
// requires C++17:
constexpr auto myArray = [] {
std::array<int, 100> result {};
for (size_t i = 0; i < 100; ++ i) {
result[i] = i * i;
}
return result;
}();
Note I used std::array<int, 100> instead of int[100] because a function cannot return a C array.
The above code requires C++17 for two reasons:
constexpr lambda
The mutable operator[] is not constexpr before C++17
Issue 1 can be easily worked-around using a separate constexpr function. Issue 2 can only be solved by defining your own array wrapper.
// requires C++14:
template <typename T, size_t n>
struct ConstexprArray {
T data[n];
constexpr ConstexprArray() : data{} {}
constexpr T& operator[](size_t i) { return data[i]; }
};
constexpr auto initialize_my_array() -> ConstexprArray<int, 100> {
ConstexprArray<int, 100> result {};
for (size_t i = 0; i < 100; ++ i) {
result[i] = i * i;
}
return result;
}
constexpr auto myArray = initialize_my_array();
Looking at your edit, I'd just answer no, because the compiler cannot transform a group of variables into an array. It just don't work that way. There isn't any construct in C++ that can take a bunch of declaration, delete them and replace it with another declaration. A source code preprocessor or generator might be able to permit the syntax you seek.
If you're interested in a solution that doesn't require external tooling, you can create a constexpr function that returns an array:
constexpr auto makeMyArray() {
std::array<int, 100> myArray{};
myArray[0] = myConstExprFunction(10);
myArray[1] = myConstExprFunction(20);
// ...
return myArray;
}
Then, initialize your array:
constexpr auto myArray = makeMyArray();
constexpr declares that it is possible to evaluate the value of the function or variable at compile time.
So the only way you could use it with array is like:
constexpr int myArray[100]{1 , 2 , 3 ,.........};
statements like
myArray[0] = myConstexprFunction(0);
can only be evaluated during runtime. So its not possible.
If you want to declare constexpr an array and initialize it's value using a constexpr function... the best I can think is wrap the array in a struct/array and initialize it via a delegate constructor.
The following is a full working C++14 example
#include <utility>
#include <iostream>
constexpr int myConstexprFunction (int i)
{ return i << 1; } // return 2*i
template <std::size_t S>
struct wrapArray
{
int const myWrappedArray[S];
template <int ... Is>
constexpr wrapArray (std::integer_sequence<int, Is...> const &)
: myWrappedArray { myConstexprFunction(Is)... }
{ }
constexpr wrapArray ()
: wrapArray(std::make_integer_sequence<int, S>())
{ }
};
int main ()
{
constexpr wrapArray<100> wa100;
for ( auto i : wa100.myWrappedArray )
std::cout << i << ", ";
std::cout << std::endl;
}
If you need a C++11 code, you have to implement a substitute for std::integer_sequence and for std::make_integer_sequence(). It's not difficult.
No.
constexpr variables must be "immediately initialised".

How to detect if a func. is a constexpr? and mark other func. constexpr depending on it?

Assuming i have some function template f1:
template<typename f2>
int f1(int i, int j) noexcept {
return i + j + f2(i, j);
}
is there way to determine if f2(i, j) can be a constexpr. (no matter it is a func. or a functor) and so mark f1<f2> as a constexpr too?
I am thinking of using SFINAE here some how, but didn't find how to detect constexpr using type traits
You can mark f1 as constexpr.
template<typename f2>
constexpr int f1(int i, int j) noexcept {
return i + j + f2(i, j);
}
The template function f1 would be constexpr iif f2 is.
if f2 is not, you will get error only when you use f1 in a constant compile time expression.
Demo
The easiest way to check whether a function (e.g., foo) is constexpr is to assign its return value to a constexpr as below:
constexpr auto i = foo();
if the returned value is not constexpr compilation will fail.
If you want a SFINAE test to check whether a function (e.g., foo) is constexpr you could use the std::integral_constant type trait:
std::integral_constant<int, foo()>::value
Live Demo
So, finally, using Jarod42 hint, i'l write and tested this example:
#include <string>
std::string S = "123567876";
constexpr size_t p() noexcept {
return 10U;
}
template<const size_t = size_t()>
constexpr size_t f(size_t i, size_t j) noexcept {
return std::move(i + j + S.size() + p());
}
#include <iostream>
int main() {
// static constexpr const auto v = f<>(1U, 2U); // error!
std::cout << f(1U, 2U) << "\n";
return 0;
}
now it's work correctly, i tested it using GCC online complier with both C++11 and C+14.
You can proof it will be really constexpr if possible by removing '+ S.size()':
...
return std::move(i + j + p());
...
and uncommenting constexpr value:
...
static constexpr const auto v = f(1U, 2U);
std::cout << v << "\n";
...
see here.
P. S. Thank you guys!

Recursive lambda functions in C++11

I am new to C++11. I am writing the following recursive lambda function, but it doesn't compile.
sum.cpp
#include <iostream>
#include <functional>
auto term = [](int a)->int {
return a*a;
};
auto next = [](int a)->int {
return ++a;
};
auto sum = [term,next,&sum](int a, int b)mutable ->int {
if(a>b)
return 0;
else
return term(a) + sum(next(a),b);
};
int main(){
std::cout<<sum(1,10)<<std::endl;
return 0;
}
compilation error:
vimal#linux-718q:~/Study/09C++/c++0x/lambda> g++ -std=c++0x sum.cpp
sum.cpp: In lambda function:
sum.cpp:18:36: error: ‘((<lambda(int, int)>*)this)-><lambda(int, int)>::sum’ cannot be used as a function
gcc version
gcc version 4.5.0 20091231 (experimental) (GCC)
But if I change the declaration of sum() as below, it works:
std::function<int(int,int)> sum = [term,next,&sum](int a, int b)->int {
if(a>b)
return 0;
else
return term(a) + sum(next(a),b);
};
Could someone please throw light on this?
Think about the difference between the auto version and the fully specified type version. The auto keyword infers its type from whatever it's initialized with, but what you're initializing it with needs to know what its type is (in this case, the lambda closure needs to know the types it's capturing). Something of a chicken-and-egg problem.
On the other hand, a fully specified function object's type doesn't need to "know" anything about what is being assigned to it, and so the lambda's closure can likewise be fully informed about the types its capturing.
Consider this slight modification of your code and it may make more sense:
std::function<int(int, int)> sum;
sum = [term, next, &sum](int a, int b) -> int {
if (a > b)
return 0;
else
return term(a) + sum(next(a), b);
};
Obviously, this wouldn't work with auto. Recursive lambda functions work perfectly well (at least they do in MSVC, where I have experience with them), it's just that they aren't really compatible with type inference.
The trick is to feed in the lambda implementation to itself as a parameter, not by capture.
const auto sum = [term, next](int a, int b) {
auto sum_impl = [term, next](int a, int b, auto& sum_ref) mutable {
if (a > b) {
return 0;
}
return term(a) + sum_ref(next(a), b, sum_ref);
};
return sum_impl(a, b, sum_impl);
};
All problems in computer science can be solved by another level of indirection. I first found this easy trick at http://pedromelendez.com/blog/2015/07/16/recursive-lambdas-in-c14/
It does require C++14 while the question is on C++11, but perhaps interesting to most.
Here's the full example at Godbolt.
Going via std::function is also possible but can result in slower code. But not always. Have a look at the answers to std::function vs template
This is not just a peculiarity about C++,
it's directly mapping to the mathematics of lambda calculus. From Wikipedia:
Lambda calculus cannot express this as directly as some other
notations:
all functions are anonymous in lambda calculus, so we can't refer to a
value which is yet to be defined, inside the lambda term defining that
same value. However, recursion can still be achieved by arranging for a
lambda expression to receive itself as its argument value
With C++14, it is now quite easy to make an efficient recursive lambda without having to incur the additional overhead of std::function, in just a few lines of code:
template <class F>
struct y_combinator {
F f; // the lambda will be stored here
// a forwarding operator():
template <class... Args>
decltype(auto) operator()(Args&&... args) const {
// we pass ourselves to f, then the arguments.
return f(*this, std::forward<Args>(args)...);
}
};
// helper function that deduces the type of the lambda:
template <class F>
y_combinator<std::decay_t<F>> make_y_combinator(F&& f) {
return {std::forward<F>(f)};
}
with which your original sum attempt becomes:
auto sum = make_y_combinator([term,next](auto sum, int a, int b) -> int {
if (a>b) {
return 0;
}
else {
return term(a) + sum(next(a),b);
}
});
In C++17, with CTAD, we can add a deduction guide:
template <class F> y_combinator(F) -> y_combinator<F>;
Which obviates the need for the helper function. We can just write y_combinator{[](auto self, ...){...}} directly.
In C++20, with CTAD for aggregates, the deduction guide won't be necessary.
In C++23, with deducing this, you don't need a Y-combinator at all:
auto sum = [term,next](this auto const& sum, int a, int b) -> int {
if (a>b) {
return 0;
}
else {
return term(a) + sum(next(a),b);
}
}
I have another solution, but work only with stateless lambdas:
void f()
{
static int (*self)(int) = [](int i)->int { return i>0 ? self(i-1)*i : 1; };
std::cout<<self(10);
}
Trick here is that lambdas can access static variables and you can convert stateless ones to function pointer.
You can use it with standard lambdas:
void g()
{
int sum;
auto rec = [&sum](int i) -> int
{
static int (*inner)(int&, int) = [](int& _sum, int i)->int
{
_sum += i;
return i>0 ? inner(_sum, i-1)*i : 1;
};
return inner(sum, i);
};
}
Its work in GCC 4.7
To make lambda recursive without using external classes and functions (like std::function or fixed-point combinator) one can use the following construction in C++14 (live example):
#include <utility>
#include <list>
#include <memory>
#include <iostream>
int main()
{
struct tree
{
int payload;
std::list< tree > children = {}; // std::list of incomplete type is allowed
};
std::size_t indent = 0;
// indication of result type here is essential
const auto print = [&] (const auto & self, const tree & node) -> void
{
std::cout << std::string(indent, ' ') << node.payload << '\n';
++indent;
for (const tree & t : node.children) {
self(self, t);
}
--indent;
};
print(print, {1, {{2, {{8}}}, {3, {{5, {{7}}}, {6}}}, {4}}});
}
prints:
1
2
8
3
5
7
6
4
Note, result type of lambda should be specified explicitly.
You can make a lambda function call itself recursively. The only thing you need to do is to is to reference it through a function wrapper so that the compiler knows it's return and argument type (you can't capture a variable -- the lambda itself -- that hasn't been defined yet).
function<int (int)> f;
f = [&f](int x) {
if (x == 0) return 0;
return x + f(x-1);
};
printf("%d\n", f(10));
Be very careful not to run out of the scope of the wrapper f.
I ran a benchmark comparing a recursive function vs a recursive lambda function using the std::function<> capture method. With full optimizations enabled on clang version 4.1, the lambda version ran significantly slower.
#include <iostream>
#include <functional>
#include <chrono>
uint64_t sum1(int n) {
return (n <= 1) ? 1 : n + sum1(n - 1);
}
std::function<uint64_t(int)> sum2 = [&] (int n) {
return (n <= 1) ? 1 : n + sum2(n - 1);
};
auto const ITERATIONS = 10000;
auto const DEPTH = 100000;
template <class Func, class Input>
void benchmark(Func&& func, Input&& input) {
auto t1 = std::chrono::high_resolution_clock::now();
for (auto i = 0; i != ITERATIONS; ++i) {
func(input);
}
auto t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count();
std::cout << "Duration: " << duration << std::endl;
}
int main() {
benchmark(sum1, DEPTH);
benchmark(sum2, DEPTH);
}
Produces results:
Duration: 0 // regular function
Duration: 4027 // lambda function
(Note: I also confirmed with a version that took the inputs from cin, so as to eliminate compile time evaluation)
Clang also produces a compiler warning:
main.cc:10:29: warning: variable 'sum2' is uninitialized when used within its own initialization [-Wuninitialized]
Which is expected, and safe, but should be noted.
It's great to have a solution in our toolbelts, but I think the language will need a better way to handle this case if performance is to be comparable to current methods.
Note:
As a commenter pointed out, it seems latest version of VC++ has found a way to optimize this to the point of equal performance. Maybe we don't need a better way to handle this, after all (except for syntactic sugar).
Also, as some other SO posts have outlined in recent weeks, the performance of std::function<> itself may be the cause of slowdown vs calling function directly, at least when the lambda capture is too large to fit into some library-optimized space std::function uses for small-functors (I guess kinda like the various short string optimizations?).
Here is a refined version of the Y-combinator solution based on one proposed by #Barry.
template <class F>
struct recursive {
F f;
template <class... Ts>
decltype(auto) operator()(Ts&&... ts) const { return f(std::ref(*this), std::forward<Ts>(ts)...); }
template <class... Ts>
decltype(auto) operator()(Ts&&... ts) { return f(std::ref(*this), std::forward<Ts>(ts)...); }
};
template <class F> recursive(F) -> recursive<F>;
auto const rec = [](auto f){ return recursive{std::move(f)}; };
To use this, one could do the following
auto fib = rec([&](auto&& fib, int i) {
// implementation detail omitted.
});
It is similar to the let rec keyword in OCaml, although not the same.
In C++23 deducing this (P0847) will be added:
auto f = [](this auto& self, int i) -> int
{
return i > 0 ? self(i - 1) + i : 0;
}
For now its only available in EDG eccp and (partially) available in MSVC:
https://godbolt.org/z/f3E3xT3fY
This is a slightly simpler implementation of the fixpoint operator which makes it a little more obvious exactly what's going on.
#include <iostream>
#include <functional>
using namespace std;
template<typename T, typename... Args>
struct fixpoint
{
typedef function<T(Args...)> effective_type;
typedef function<T(const effective_type&, Args...)> function_type;
function_type f_nonr;
T operator()(Args... args) const
{
return f_nonr(*this, args...);
}
fixpoint(const function_type& p_f)
: f_nonr(p_f)
{
}
};
int main()
{
auto fib_nonr = [](const function<int(int)>& f, int n) -> int
{
return n < 2 ? n : f(n-1) + f(n-2);
};
auto fib = fixpoint<int,int>(fib_nonr);
for (int i = 0; i < 6; ++i)
{
cout << fib(i) << '\n';
}
}
C++ 14:
Here is a recursive anonymous stateless/no capture generic set of lambdas
that outputs all numbers from 1, 20
([](auto f, auto n, auto m) {
f(f, n, m);
})(
[](auto f, auto n, auto m) -> void
{
cout << typeid(n).name() << el;
cout << n << el;
if (n<m)
f(f, ++n, m);
},
1, 20);
If I understand correctly this is using the Y-combinator solution
And here is the sum(n, m) version
auto sum = [](auto n, auto m) {
return ([](auto f, auto n, auto m) {
int res = f(f, n, m);
return res;
})(
[](auto f, auto n, auto m) -> int
{
if (n > m)
return 0;
else {
int sum = n + f(f, n + 1, m);
return sum;
}
},
n, m); };
auto result = sum(1, 10); //result == 55
Here's the proof that a recursive lambda with a small body almost has the same performance like a usual recursive fuction which can call itself directly.
#include <iostream>
#include <chrono>
#include <type_traits>
#include <functional>
#include <atomic>
#include <cmath>
using namespace std;
using namespace chrono;
unsigned recursiveFn( unsigned x )
{
if( x ) [[likely]]
return recursiveFn( x - 1 ) + recursiveFn( x - 1 );
else
return 0;
};
atomic_uint result;
int main()
{
auto perf = []( function<void ()> fn ) -> double
{
using dur_t = high_resolution_clock::duration;
using urep_t = make_unsigned_t<dur_t::rep>;
high_resolution_clock::duration durMin( (urep_t)-1 >> 1 );
for( unsigned r = 10; r--; )
{
auto start = high_resolution_clock::now();
fn();
dur_t dur = high_resolution_clock::now() - start;
if( dur < durMin )
durMin = dur;
}
return durMin.count() / 1.0e9;
};
auto recursiveLamdba = []( auto &self, unsigned x ) -> unsigned
{
if( x ) [[likely]]
return self( self, x - 1 ) + self( self, x - 1 );
else
return 0;
};
constexpr unsigned DEPTH = 28;
double
tLambda = perf( [&]() { ::result = recursiveLamdba( recursiveLamdba, DEPTH ); } ),
tFn = perf( [&]() { ::result = recursiveFn( DEPTH ); } );
cout << trunc( 1000.0 * (tLambda / tFn - 1.0) + 0.5 ) / 10.0 << "%" << endl;
}
For my AMD Zen1 CPU with current MSVC the recursiveFn is about 10% faster. For my Phenom II x4 945 with g++ 11.1.x both functions have the same performance.
Keep in mind that this is almost the worst case since the body of the funtion is very small. If it is larger the part of the recursive function call itself is smaller.
You're trying to capture a variable (sum) you're in the middle of defining. That can't be good.
I don't think truely self-recursive C++0x lambdas are possible. You should be able to capture other lambdas, though.
Here is the final answer for the OP. Anyway, Visual Studio 2010 does not support capturing global variables. And you do not need to capture them because global variable is accessable globally by define. The following answer uses local variable instead.
#include <functional>
#include <iostream>
template<typename T>
struct t2t
{
typedef T t;
};
template<typename R, typename V1, typename V2>
struct fixpoint
{
typedef std::function<R (V1, V2)> func_t;
typedef std::function<func_t (func_t)> tfunc_t;
typedef std::function<func_t (tfunc_t)> yfunc_t;
class loopfunc_t {
public:
func_t operator()(loopfunc_t v)const {
return func(v);
}
template<typename L>
loopfunc_t(const L &l):func(l){}
typedef V1 Parameter1_t;
typedef V2 Parameter2_t;
private:
std::function<func_t (loopfunc_t)> func;
};
static yfunc_t fix;
};
template<typename R, typename V1, typename V2>
typename fixpoint<R, V1, V2>::yfunc_t fixpoint<R, V1, V2>::fix = [](tfunc_t f) -> func_t {
return [f](fixpoint<R, V1, V2>::loopfunc_t x){ return f(x(x)); }
([f](fixpoint<R, V1, V2>::loopfunc_t x) -> fixpoint<R, V1, V2>::func_t{
auto &ff = f;
return [ff, x](t2t<decltype(x)>::t::Parameter1_t v1,
t2t<decltype(x)>::t::Parameter1_t v2){
return ff(x(x))(v1, v2);
};
});
};
int _tmain(int argc, _TCHAR* argv[])
{
auto term = [](int a)->int {
return a*a;
};
auto next = [](int a)->int {
return ++a;
};
auto sum = fixpoint<int, int, int>::fix(
[term,next](std::function<int (int, int)> sum1) -> std::function<int (int, int)>{
auto &term1 = term;
auto &next1 = next;
return [term1, next1, sum1](int a, int b)mutable ->int {
if(a>b)
return 0;
else
return term1(a) + sum1(next1(a),b);
};
});
std::cout<<sum(1,10)<<std::endl; //385
return 0;
}
This answer is inferior to Yankes' one, but still, here it goes:
using dp_type = void (*)();
using fp_type = void (*)(dp_type, unsigned, unsigned);
fp_type fp = [](dp_type dp, unsigned const a, unsigned const b) {
::std::cout << a << ::std::endl;
return reinterpret_cast<fp_type>(dp)(dp, b, a + b);
};
fp(reinterpret_cast<dp_type>(fp), 0, 1);
You need a fixed point combinator. See this.
or look at the following code:
//As decltype(variable)::member_name is invalid currently,
//the following template is a workaround.
//Usage: t2t<decltype(variable)>::t::member_name
template<typename T>
struct t2t
{
typedef T t;
};
template<typename R, typename V>
struct fixpoint
{
typedef std::function<R (V)> func_t;
typedef std::function<func_t (func_t)> tfunc_t;
typedef std::function<func_t (tfunc_t)> yfunc_t;
class loopfunc_t {
public:
func_t operator()(loopfunc_t v)const {
return func(v);
}
template<typename L>
loopfunc_t(const L &l):func(l){}
typedef V Parameter_t;
private:
std::function<func_t (loopfunc_t)> func;
};
static yfunc_t fix;
};
template<typename R, typename V>
typename fixpoint<R, V>::yfunc_t fixpoint<R, V>::fix =
[](fixpoint<R, V>::tfunc_t f) -> fixpoint<R, V>::func_t {
fixpoint<R, V>::loopfunc_t l = [f](fixpoint<R, V>::loopfunc_t x) ->
fixpoint<R, V>::func_t{
//f cannot be captured since it is not a local variable
//of this scope. We need a new reference to it.
auto &ff = f;
//We need struct t2t because template parameter
//V is not accessable in this level.
return [ff, x](t2t<decltype(x)>::t::Parameter_t v){
return ff(x(x))(v);
};
};
return l(l);
};
int _tmain(int argc, _TCHAR* argv[])
{
int v = 0;
std::function<int (int)> fac =
fixpoint<int, int>::fix([](std::function<int (int)> f)
-> std::function<int (int)>{
return [f](int i) -> int{
if(i==0) return 1;
else return i * f(i-1);
};
});
int i = fac(10);
std::cout << i; //3628800
return 0;
}