C++11 lambda and template specialization - c++

I would like to know what is the correct type definition for the lambda presented below, so that the following code will compile using a conformant c++11 compiler:
#include <cstdio>
#include <string>
template<class Func>
class foo
{
public:
foo(Func func)
: fum(func){}
Func fum;
};
int main()
{
foo<???> fi([](int i) -> bool { printf("%d",i); return true; });
fi.fum(2);
return 0;
}
I guess another way it could be done is like so:
template<typename Func>
foo<Func> make_foo(Func f)
{
return foo<Func>(f);
}
int main()
{
auto fi = make([](int i) -> bool { printf("%d",i); return true; });
fi.fum(2);
return 0;
}

It's auto + decltype:
auto l = [](int i) -> bool { printf("%d",i); return true; };
foo<decltype(l)> fi(l);
fi.fum();
Every single lambda has a different, unique, unnamed type. You, as a coder, just can not name it.
However, in your case, since the lambda doesn't capture anything (empty []), it is implicitly convertible to a pointer-to-function, so this would do:
foo<bool(*)(int)> fi([](int i) -> bool { printf("%d",i); return true; });
fi.fum();

It's std::function<bool(int)>. Or possibly just bool(*)(int) if you prefer, since the lambda doesn't capture.
(The raw function pointer might be a bit more efficient, since std::function does (at least in some cases) require dynamic allocation for some type erasure magic.)

Related

How to initialize a boost rolling window accumulator?

I would like to initialize a boost rolling window accumulator without having to do an assignment inside a function call.
This is what I see everyone do:
boost::accumulators::accumulator_set<double, boost::accumulators::stats<boost::accumulators::tag::rolling_mean>> acc(boost::accumulators::tag::rolling_window::window_size = 10);
How could I make the same accumulator without having the assignment inside the constructor call above?
It's not an assignment, it's a named-argument idiom. C++ doesn't have that, really, so this why it looks like an assignment: it's an Expression Template
You could of course figure out the type and use it, but that would not make any difference and just make it harder to use the library correctly:
boost::parameter::aux::tagged_argument_list_of_1<
boost::parameter::aux::tagged_argument<
boost::accumulators::tag::rolling_window_size_<0>, const int>>
init(10);
ba::accumulator_set<double, ba::stats<ba::tag::rolling_mean>> acc(init);
I don't know about you, but I prefer the named-argument expression.
You can obviously write a helper function to remove the library details:
auto make_accum(int window) {
return ba::accumulator_set<
double,
ba::stats<ba::tag::rolling_mean>> (ba::tag::rolling_window::window_size = window);
}
int main() {
auto acc = make_accum(10);
}
This simply made the named argument into a positional argument using the knowledge about the statistics in in your set.
If you're worried about generic code, just pass the expression as the initializer in generic cases. That's how the library istelf is implemented:
template <typename Stats, typename... Init> auto generic_accum(Init const&... init) {
return ba::accumulator_set<double, Stats> (init...);
}
Demo All 3 Approaches
Live On Coliru
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/rolling_mean.hpp>
namespace ba = boost::accumulators;
template <typename Stats, typename... Init> auto generic_accum(Init const&... init) {
return ba::accumulator_set<double, Stats> (init...);
}
auto make_accum(int window) {
return ba::accumulator_set<
double,
ba::stats<ba::tag::rolling_mean>> (ba::tag::rolling_window::window_size = window);
}
int main() {
{
boost::parameter::aux::tagged_argument_list_of_1<
boost::parameter::aux::tagged_argument<
boost::accumulators::tag::rolling_window_size_<0>, const int>>
init(10);
ba::accumulator_set<double, ba::stats<ba::tag::rolling_mean>>
acc(init);
}
{
auto acc = make_accum(10);
}
{
auto acc = generic_accum<ba::stats<ba::tag::rolling_mean>>(ba::tag::rolling_window::window_size = 10);
}
}

C++: How to initialize and call a method on std::optional?

Let's consider this code
std::optional<flat_set<int>> object;
void f(int v) {
if (!object.has_value()) {
object = flat_set<int>{};
}
object->insert(v);
}
How can I avoid if part?
Is there any way to write the body of function in one line by calling one method?
There isn't much you can do to avoid the if unless you absolutely know that the optional has a value (and if you know, why use an optional?)
You could wrap the conditional part into a lambda/function:
#include <optional>
#include <boost/container/flat_set.hpp>
std::optional<boost::container::flat_set<int> > objects;
void f(int _v)
{
auto assure = [&]() -> decltype(auto)
{
if (objects.has_value())
return *objects;
else
return objects.emplace();
};
assure().insert(_v);
}
another way...
#include <optional>
#include <boost/container/flat_set.hpp>
std::optional<boost::container::flat_set<int> > objects;
template<class T>
auto assure_contents(std::optional<T>& opt) -> T&
{
if (opt.has_value())
return *opt;
else
return opt.emplace();
}
void f(int _v)
{
assure_contents(objects).insert(_v);
}

Can't manage to figure out the syntax of C++ lamda expression as a method's parameter

Question:
How do you pass a lambda expression into a function. for example:
int GetCoolInt()
{
int a = 3;
return AddToInt( [a] (int b) {
a += b;
});
}
int AddToInt(int func(int output))
{
return func(3);
}
int output = GetCoolInt();
Context of my issue:
I have the following 2 methods:
FindPlayerStartByTag calls FindActor to use logic that will be used in other methods.
//template <typename T>
APlayerStart* FindPlayerStartByTag(FName tag)
{
return FindActor<APlayerStart>(tag, [tag](TObjectIterator<APlayerStart> actor) {
APlayerStart* playerStart;
if (actor->PlayerStartTag == tag)
{
playerStart = *actor;
}
return playerStart;
});
}
This method is the logic to find a specific object in an iterator with the help of the FindPlayerStartByTag logic
template <typename T>
T* FindActor(FName tag, T* func(TObjectIterator<T> actor))
{
T* returnValue;
if (!tag.IsNone())
{
// Search for actor
for (TObjectIterator<T> itr; itr; ++itr)
{
if (itr->IsA(T::StaticClass()))
{
returnValue = func(itr);
if (returnValue)
{
break;
}
}
}
}
return returnValue;
}
I currently have this error:
I'm confused as to what it means, considering a third method:
template <typename T>
T* FindActorByTag(FName tag)
{
return FindActor<T>(tag, [tag](TObjectIterator<AActor> actor)
{
T* foundActor;
for (FName currentActorTag : actor->Tags)
{
if (tag == currentActorTag)
{
foundActor = *actor;
}
}
return foundActor;
});
}
compiles just fine.
I can see that by adding template <typename T> gets rid of the error (see the //template <typename T>, but i don't need this as in the case of APlayerStart, i am already aware of what type the method needs to be.
Anyone help explain this?
Thanks!
Edit:
Here is a version of the method that i was using before i refactored into here:
APlayerStart* FindPlayerStartByTag(FName tag)
{
/*return FindActor<APlayerStart>(tag, [tag](TObjectIterator<APlayerStart> actor) {
APlayerStart* playerStart;
if (actor->PlayerStartTag == tag)
{
playerStart = *actor;
}
return playerStart;
});*/
APlayerStart* returnValue;
if (!tag.IsNone())
{
// Search for actor
for (TObjectIterator<APlayerStart> itr; itr; ++itr)
{
if (itr->IsA(APlayerStart::StaticClass()) && itr->PlayerStartTag == tag)
{
returnValue = *itr;
}
}
}
return returnValue;
}
but compiles.
Edit 2:
This is how i intend on using the methods:
PlayerStart = ActorHelper->FindPlayerStartByTag(PlayerStartTag);
ATreasureChestActor* treasureChestActor = ActorHelper->FindActorByTag<ATreasureChestActor>(TreasureActorTagName);
Edit 3:
The issue seems to be coming from the closure usage!
This is with the use of a closure variable:
and this is without:
Your post is still a mess, with 4 different versions of the same issue. I will focus on the first code snippet as it seems to be the closest one to a [MCVE] and I will clarify how to properly use lambdas and function objects.
int AddToInt(int func(int output))
This is a little bit misleading. I suggest changing it to the equivalent, but more used:
int AddToInt(int (*func)(int))
This means: declaring a function named AddToInt which:
accepts a parameter of type "pointer to function accepting an int and returning an int" and
returns an int.
As you can see, your function accept a classic C function pointer. It won't accept a function object of any type. To note here is that lambdas without capture can be converted to a function pointer.
For instance keeping the above declaration:
AddToInt([](int b) { return b + 1; }); // ok, non-capturing lambda conversion to function pointer
AddToInt([a](int b) { return a + b; }); // error cannot convert capturing lambda to function pointer
The reason is simple to understand. A non-capturing lambda can be equivalent to a free function, but a capturing lambda has a state (formed by the capture set), so it is "more" than a simple, classical free function.
As you can see, accepting function pointers is very much an archaic idiom because of these limitations (and don't even think of passing any kind of function object - e.g. a class with operator() defined).
For accepting any kind of callable object you generally have two options: the general template or the standard std::function object.
Template object
template <class Fn>
int AddToInt1(Fn func)
{
return func(3);
}
Now you can call AddToInt1 with any kind of callable. Depending of the type of the deduced Fn type you can have zero overhead with this method. A downside is that you can accept any type, including non-callable ones, or ones with incorrect parameter or return types. Concepts will alleviate most of these downsides.
AddToInt1([](int b) { return b + 1; }); // OK
AddToInt1([a](int b) { return a + b; }); // OK
You also might want to add perfect forwarding (omitted in the example for brevity).
std::function
The other route is to use std::function:
int AddToInt2(std::function<int(int)> func)
The disadvantage here is the heaviness of the std::function object. It uses type erasure and that adds a significant amount of performance penalty (which can be perfectly acceptable depending on your usage).
AddToInt2([](int b) { return b + 1; }); // OK
AddToInt2([a](int b) { return a + b; }); // OK
Now, once you get the gist of the above there are some more problems with your code you need to figure out:
[a] (int b) { a += b;};
First of all, are you aware that this lambda does not return anything? Furthermore it tries to modify the captured by value a which is illegal, as the lambda's operator() is const by default for good reason. If you want the lambda to modify the outer a captured variable, then you need to capture it by reference:
[&a] (int b) { a += b;};
And now you have to really really be careful to not end up with a dangling reference.
But I suspect you meant:
AddToInt([a] (int b) { return a + b;});
But that is just pure speculation on my part.
Here is a fully working example:
template <class Fn>
int AddToInt1(Fn func)
{
return func(3);
}
int AddToInt2(std::function<int (int)> func)
{
return func(3);
}
int GetCoolInt()
{
int a = 3;
return AddToInt1([a] (int b) { return a + b;}); // OK
//return AddToInt2([a] (int b) { return a + b;}); // OK
}
There are some important points I just mentioned here, but elaborating on them would be equivalent to writing a full tutorial on lambdas and beyond, which is out of the scope of this site. In conclusion you have to study the subject on your own.

Attempting to use lambda function in static function (C++)

why is this code invalid?. I don't know if I am using the lambda sintax correctly, but based on other posts, it looks fine.
struct foo{
static int faa(int x);
};
int foo::faa(int x){
bool isCon = []() {
return true;
};
return isCon();
}
Lambdas have indeterminate type, so you can't know which type will one have. Obviously, the lambda you defined won't be of type bool (it may return a bool, but it's not one), so you would do this instead:
struct foo{
static int faa(int x);
};
int foo::faa(int x){
auto isCon = []()->bool {
return true;
};
return isCon();
}
Here, the auto keyword tells the compiler to deduce the type for you. The ->bool expression tells the compiler that the lambda will return a bool.
However, your foo::faa() function returns an int, so a cast may ocurr because your lambda may return a bool (which has nothing to do with the question, but watch out).

Map from int to type specifier

I want to use a map to refer to a type specifier mainly to shorten my code from multiple uses of
std::unique_ptr< Class >(new class1);
to
std::unique_ptr< Class >(new sampleMap[enum1]);
and then define my map so that it refers each enum value (enum1, enum2, ...) to my classes (class1, class2, ...).
But I cannot define my map with the values being a type name like this
std::map < int, Class > mapName {
{0, class1},
{0, class1},
...
};
since type name is not allowed in maps.
The main reason I'm looking for an answer for this is to make my code more succinct by replacing a series of "if/else if" statements or "switch-case" statements into only one line of code where the output std::unique_ptr<Class>(new class1); is dynamically figured out through the map that I define. So, I just input the enum number and get the corresponding class instantiated for me. Otherwise, I would have to do this:
if (enum1 = 0)
{
std::unique_ptr< Class >(new class1);
}
else if (enum2 = 0)
{
std::unique_ptr< Class >(new class2);
}
(or a switch-case)
But I want to do all above in one line like this:
std::unique_ptr<Class>(new sampleMap[enum1]);
plus the map declaration.
Any clue how this could be done?
You cannot easily implement an std::map that will return types as values the way you are trying to do it. You would need to implement your own class that would represent types as values. However, since your goal seems to be to create instances of objects where the concrete type depends on a value, an easily solution is to make a map of functions instead. This assumes that all the types you want to support derive from a common type. Each value can hold a function which constructs the correct object. If your types do not derive from a common type, then you will need to preform further type erasure (perhaps with std::any).
#include <functional>
#include <iostream>
#include <map>
#include <memory>
// Simple set of classes
// Class is the base type
// Class1 and Class2 derive from Class
struct Class { virtual void func() = 0; };
struct Class1 : Class {
void func() override { std::cout << "Class1\n"; }
};
struct Class2 : Class {
void func() override { std::cout << "Class2\n"; }
};
// A map of factory functions
const std::map<int, std::function<std::unique_ptr<Class>()>> mapName = {
{ 1, []() {return std::make_unique<Class1>(); } },
{ 2, []() {return std::make_unique<Class2>(); } }
};
int main()
{
auto foo = mapName.at(2)(); // Make an object of type associated with the value 2
foo->func(); // Prints "Class2\n"
return 0;
}
Depending on where you want to use this code, you might want to do this with an if-else chain. std::functions are usually very difficult for the compiler to optimize, so if you expect this code to be called frequently enough, it's probably more efficient to just code it out:
(using #FrançoisAndrieux's example)
#include <iostream>
#include <memory>
#include <stdexcept>
// Simple set of classes
// Class is the base type
// Class1 and Class2 derive from Class
struct Class {
virtual void func() = 0;
};
struct Class1 : Class {
void func() override { std::cout << "Class1\n"; }
};
struct Class2 : Class {
void func() override { std::cout << "Class2\n"; }
};
std::unique_ptr<Class> make_class(int i)
{
if (i == 0) return std::make_unique<Class1>();
else if (i == 1) return std::make_unique<Class2>();
throw std::out_of_range{ "Asked to construct an unknown type" };
}
int main()
{
auto foo = make_class(1); // Make an object of type associated with the value 1
foo->func(); // Prints "Class2\n"
return 0;
}
If the number of values is large, you might gain by doing a binary search (or just a switch):
// If there are 128 elements, for example
if (!(0 <= i && i < 128)) throw std::out_of_range{ "..." };
if (i < 64) {
if (i < 32) {
...
} else {
...
}
} else {
...
}
It's messy but it's only in one place.
To make a more optimizable version, you can do some minimal metaprogramming / expression templates:
#include <iostream>
#include <memory>
#include <stdexcept>
#include <type_traits>
#include <utility>
// Simple set of classes
// Class is the base type
// Class1 and Class2 derive from Class
struct Class {
virtual void func() = 0;
};
struct Class1 : Class {
void func() override { std::cout << "Class1\n"; }
};
struct Class2 : Class {
void func() override { std::cout << "Class2\n"; }
};
template<typename R, typename SwBase, typename T, typename F>
struct Switch
{
SwBase base;
T value;
F fn;
constexpr Switch(SwBase base, T value, F fn)
: base{ std::move(base) }
, value{ std::move(value) }
, fn{ std::move(fn) }
{}
constexpr R operator()(T val) const {
if (value == val) return fn();
return base(val);
}
};
template<typename R, typename SwBase, typename T, typename F>
constexpr auto make_switch_impl(SwBase&& swb, T&& t, F&& f)
{
return Switch<R, std::decay_t<SwBase>, std::decay_t<T>, std::decay_t<F>> {
std::forward<SwBase>(swb),
std::forward<T>(t),
std::forward<F>(f),
};
}
template<typename R>
constexpr auto make_switch(char const* failMsg)
{
return [=](auto&&) -> R { throw std::out_of_range{ failMsg }; };
}
template<typename R, typename T, typename F, typename... Args>
constexpr auto make_switch(char const* failMsg, T&& val, F&& fn, Args&&... args)
{
return make_switch_impl<R>(
make_switch<R>(failMsg, std::forward<Args>(args)...),
std::forward<T>(val),
std::forward<F>(fn)
);
}
auto make_class(int i)
{
return make_switch<std::unique_ptr<Class>>(
"Asked to construct an unknown type",
0, [] { return std::make_unique<Class1>(); },
1, [] { return std::make_unique<Class2>(); }
)(i);
}
int main()
{
auto foo = make_class(1); // Make an object of type associated with the value 1
foo->func(); // Prints "Class2\n"
return 0;
}
The switch statement would turn into this:
auto make_class(int i)
{
return make_switch<std::unique_ptr<Class>>(
"Asked to construct an unknown type",
0, [] { return std::make_unique<Class1>(); },
1, [] { return std::make_unique<Class2>(); }
)(i);
}
You could also store the "switch" separately, although this makes it less optimizable (down to roughly the same level as François Andrieux's solution):
const auto mapName = make_switch<std::unique_ptr<Class>>(
"Asked to construct an unknown type",
0, [] { return std::make_unique<Class1>(); },
1, [] { return std::make_unique<Class2>(); }
);
auto make_class(int i)
{
return mapName(i);
}
This version, and also raw if-else chains, let the compiler optimize the make_class function to the equivalent of a switch statement. Also, the main function:
int main()
{
auto foo = make_class(1); // Make an object of type associated with the value 1
foo->func(); // Prints "Class2\n"
return 0;
}
Can be optimized to the equivalent of:
int main()
{
std::cout << "Class2\n";
return 0;
}
Whereas storing the std::function or the other less efficient tricks I've mentioned makes it much more difficult for the compiler to optimize it fully (I haven't found one that does).
Note that out of GCC, Clang, Visual C++, and the Intel compiler, only Clang was able to completely optimize the main function using this Switch struct. GCC and Visual C++ were able to optimize it to a call to Class2's func(). The Intel compiler doesn't seem to have optimized it at all (but maybe I don't know the right flags for it)