std::vector of movable-only lambdas, is it possible? - c++

I'd like to have a collection of lambdas, with the requirement that the lambas must not be copied, only moved.
This is because the lambas may need to move-capture some of their arguments that are not copy-constructible.
Example:
NonCopyableType varName ;
auto func = [a=move(varName)](){ ... } ; //varName is move-captured
After this I want to store func in a vector, but I can't use the std::function type because it requires the lambdas to be copyable.
vector<function<void()>> list ;
list.push_back(func) ; //won't work
Is it possible to do this some other way?

Sure. Just write your own function clone that is move-only. Here's a simplified version that only supports nullary callables, but you can see how it can be extended:
class move_function
{
struct placeholder {
virtual ~placeholder() = default;
virtual void call() = 0;
};
template <class T>
struct holder : placeholder {
T f;
void call() override { f(); }
};
std::unique_ptr<placeholder> f_;
public:
template <class F,
class R = std::result_of_t<F&()>,
std::enable_if_t<!std::convertible<std::decay_t<F>*, move_function*>::value, int> = 0>
move_function(F&& f)
: f_(new std::decay_t<F>{std::forward<F>(f)})
{ }
void operator()() const { f_->call(); }
};
All the implicitly defined special member functions already do the right thing for us.

Related

c++ lambda inside member class function, is it possible?

I have a base class with a vector of pointers, and I think to slide the vector outside this class, I wrote the for_each() method:
class model {
static std::vector<model*> models;
...
public:
template <class C>
static void for_each(C *c,void (C::*f)(model *))
{
for (std::vector<model*>::iterator it=models.begin(); it!=models.end(); ++it) {
c->f(*it);
}
...
}
I tryed to use for_each() in a member function:
void v_context::build_cmd()
{
...
auto f1=[&](model* m)->void{commandBuffers.push_back(*(m->build_secondary_buffers(inheritanceInfo, pipelines.gltf)));};
model::for_each<VulkanExample,void (VulkanExample::*)(model*)>(this,f1);
...
}
The compiler (gcc version 10.2.1 20210110 (Debian 10.2.1-6)), rightly returns the error:
error: cannot convert ‘v_context::build_cmd()::<lambda(model*)>’ to
‘void (v_context::)(model)’
note: initializing argument 2 of ‘static void model::for_each(C*, void
(C::)(model)) [with C=v_context]’
Is it possible? Does correct syntax template exist?
The simplest is probably to make it even more generic:
class model {
static std::vector<model *> models;
public:
template <class Func>
static void for_each(Func&& func) { // no instance needed
for (auto ptr : models) { // simplified loop
func(ptr);
}
}
};
Then just capture [this] in the lambdas you use it with:
void VulkanExample::build_cmd() {
auto f1 = [this](model *m) {
// ...
};
model::for_each(f1);
}
Demo
You could use std::invoke to implement this logic. A class and a member function pointer this would require swapping the parameters, but otherwise this would allow you to pass any number of additional parameters before the model* parameter:
class model
{
...
template <class F, class...Args>
static void for_each(F&& f, Args&&...args)
{
for (auto p : models)
{
std::invoke(f, args..., p);
}
}
...
};
Example usages:
struct Foo
{
void Bar(model*) {}
};
...
Foo foo;
model::for_each(&Foo::Bar, foo);
model::for_each([&](model* m)->void{commandBuffers.push_back(*(m->build_secondary_buffers(inheritanceInfo, pipelines.gltf)));});

How to initiate std::unique_ptr in the constructor with std::make_unique() [duplicate]

I have a class with a unique_ptr member.
class Foo {
private:
std::unique_ptr<Bar> bar;
...
};
The Bar is a third party class that has a create() function and a destroy() function.
If I wanted to use a std::unique_ptr with it in a stand alone function I could do:
void foo() {
std::unique_ptr<Bar, void(*)(Bar*)> bar(create(), [](Bar* b){ destroy(b); });
...
}
Is there a way to do this with std::unique_ptr as a member of a class?
Assuming that create and destroy are free functions (which seems to be the case from the OP's code snippet) with the following signatures:
Bar* create();
void destroy(Bar*);
You can write your class Foo like this
class Foo {
std::unique_ptr<Bar, void(*)(Bar*)> ptr_;
// ...
public:
Foo() : ptr_(create(), destroy) { /* ... */ }
// ...
};
Notice that you don't need to write any lambda or custom deleter here because destroy is already a deleter.
It's possible to do this cleanly using a lambda in C++11 (tested in G++ 4.8.2).
Given this reusable typedef:
template<typename T>
using deleted_unique_ptr = std::unique_ptr<T,std::function<void(T*)>>;
You can write:
deleted_unique_ptr<Foo> foo(new Foo(), [](Foo* f) { customdeleter(f); });
For example, with a FILE*:
deleted_unique_ptr<FILE> file(
fopen("file.txt", "r"),
[](FILE* f) { fclose(f); });
With this you get the benefits of exception-safe cleanup using RAII, without needing try/catch noise.
You just need to create a deleter class:
struct BarDeleter {
void operator()(Bar* b) { destroy(b); }
};
and provide it as the template argument of unique_ptr. You'll still have to initialize the unique_ptr in your constructors:
class Foo {
public:
Foo() : bar(create()), ... { ... }
private:
std::unique_ptr<Bar, BarDeleter> bar;
...
};
As far as I know, all the popular c++ libraries implement this correctly; since BarDeleter doesn't actually have any state, it does not need to occupy any space in the unique_ptr.
Unless you need to be able to change the deleter at runtime, I would strongly recommend using a custom deleter type. For example, if use a function pointer for your deleter, sizeof(unique_ptr<T, fptr>) == 2 * sizeof(T*). In other words, half of the bytes of the unique_ptr object are wasted.
Writing a custom deleter to wrap every function is a bother, though. Thankfully, we can write a type templated on the function:
Since C++17:
template <auto fn>
struct deleter_from_fn {
template <typename T>
constexpr void operator()(T* arg) const {
fn(arg);
}
};
template <typename T, auto fn>
using my_unique_ptr = std::unique_ptr<T, deleter_from_fn<fn>>;
// usage:
my_unique_ptr<Bar, destroy> p{create()};
Prior to C++17:
template <typename D, D fn>
struct deleter_from_fn {
template <typename T>
constexpr void operator()(T* arg) const {
fn(arg);
}
};
template <typename T, typename D, D fn>
using my_unique_ptr = std::unique_ptr<T, deleter_from_fn<D, fn>>;
// usage:
my_unique_ptr<Bar, decltype(&destroy), destroy> p{create()};
You know, using a custom deleter isn't the best way to go, as you will have to mention it all over your code.
Instead, as you are allowed to add specializations to namespace-level classes in ::std as long as custom types are involved and you respect the semantics, do that:
Specialize std::default_delete:
template <>
struct ::std::default_delete<Bar> {
default_delete() = default;
template <class U>
constexpr default_delete(default_delete<U>) noexcept {}
void operator()(Bar* p) const noexcept { destroy(p); }
};
And maybe also do std::make_unique():
template <>
inline ::std::unique_ptr<Bar> ::std::make_unique<Bar>() {
auto p = create();
if (!p)
throw std::runtime_error("Could not `create()` a new `Bar`.");
return { p };
}
You can simply use std::bind with a your destroy function.
std::unique_ptr<Bar, std::function<void(Bar*)>> bar(create(), std::bind(&destroy,
std::placeholders::_1));
But of course you can also use a lambda.
std::unique_ptr<Bar, std::function<void(Bar*)>> ptr(create(), [](Bar* b){ destroy(b);});
#include "fmt/core.h"
#include <memory>
class example {};
void delete_example(example *)
{
fmt::print("delete_example\n");
}
using example_handle = std::unique_ptr<example, decltype([] (example * p)
{
delete_example(p);
})>;
int main()
{
example_handle handle(new example);
}
Just my two cents, using C++20.
https://godbolt.org/z/Pe3PT49h4
With a lambda you can get the same size as a plain std::unique_ptr. Compare the sizes:
plain: 8
lambda: 8
fpointer: 16
std::function: 40
Which is the output of the following. (I declared the lambda outside the scope of the class. Not sure if you can scope it inside the class.)
#include <iostream>
#include <memory>
#include <functional>
struct Bar {};
void destroy(Bar* b) {}
Bar* create() { return 0; }
auto lambda_destroyer = [](Bar* b) {destroy(b);};
class Foo {
std::unique_ptr<Bar, decltype(lambda_destroyer)> ptr_;
public:
Foo() : ptr_(create(), lambda_destroyer) { /* ... */ }
};
int main()
{
std::cout << "plain: " << sizeof (std::unique_ptr<Bar>) << std::endl
<< "lambda: " << sizeof (std::unique_ptr<Bar, decltype(lambda_destroyer)>) << std::endl
<< "fpointer: " << sizeof (std::unique_ptr<Bar, void(*)(Bar*)>) << std::endl
<< "std::function: " << sizeof (std::unique_ptr<Bar, std::function<void(Bar*)>>) << std::endl;
}
I'm fairly convinced that this is the best current way to do it:
#include <memory>
#include <stdio.h>
template <typename T, auto fn>
struct Deleter
{
void operator()(T *ptr)
{
fn(ptr);
}
};
template <typename T, auto fn>
using handle = std::unique_ptr<T, Deleter<T, fn>>;
using file = handle<FILE, fclose>;
int main()
{
file f{fopen("a.txt", "w")};
return 0;
}
Because you've specified a Functor as the deleter in the unique_ptr's template arguments, you don't need to set a deleter when calling its constructor.
The Deleter functor uses "template auto" to take a deletion function (in this example: fclose) as a template argument, so this needs C++17.
Expanding it to support other types is just one extra "using" line per type.
Simple is also:
class Foo {};
class Bar
{
public:
Bar()
{
// actual initialisation at some point
}
private:
std::unique_ptr<Foo, void(*)(Foo*)> foo = {{}, {}}; // or = {nullptr, {}}
};
Sure, you can also create some helper function to do the job to not have the initial state at any time.
In fact, in your specific scenario, the cleanest way is to actually put your Bar (not mine, sorry for the confusion) into a simple wrapper class, which makes reuse easier.

Passing different datatypes via a loop

Lets say I have a function
template<typename T>
some_function(T a){
// some operations..
}
I have a huge list of classes who objects i want to pass to the function one by one(Don't ask me why I'm forced to have it like that.)
class type1{ //.. whateever is necessary here...
};
class type2{ //.. whateever is necessary here...
};
class type3{ //.. whateever is necessary here...
};
class type4{ //.. whateever is necessary here...
};
.
.
and so on
Is there a way I can instantiate an object of each data and pass it to the function within a loop, rather than type one by one it manually.
(It would be better if the instantiation happens within the loop so that the object is local for every loop).
Any way to approach this problem other than typing it manually is welcome.
EDIT:
Since there were questions in the comments. Let me elaborate on the type of algorithm I am looking for.
Step 1: Pick a class my_class in [type1,type2,...,typeN]
Step 2: Instantiate an object of that class my_class object
Step 3: Pass it to the function some_function(object)
Step 4: Go to step 1 and pick the next class.
I hope I made things clear.
EDIT 2: I use c++11 . But I don't mind switching if it is needed
Let me elaborate on the type of algorithm I am looking for.
Step 1: Pick a class my_class in [type1,type2,...,typeN]
Step 2: Instantiate an object of that class my_class object
Step 3: Pass it to the function some_function(object)
Step 4: Go to step 1 and pick the next class.
If you can use C++11 or newer, and if you can pass immediately the object instantiated to some_function(), you can simulate a loop with a variadic template type list as follows
template <typename ... Ts>
void repeatOverTypes ()
{
using unused=int[];
(void)unused { 0, (some_function(Ts{}), 0)... };
}
The following is a full compiling example
#include <iostream>
class type_1 { };
class type_2 { };
class type_3 { };
class type_4 { };
template <typename T>
void some_function (T a)
{ }
template <typename ... Ts>
void repeatOverTypes ()
{
using unused=int[];
(void)unused { 0, (some_function(Ts{}), 0)... };
}
int main ()
{
repeatOverTypes<type_1, type_2, type_3, type_4>();
}
If you can use C++17, using folding repeatOverTypes() become simply
template <typename ... Ts>
void repeatOverTypes ()
{ (some_function(Ts{}), ...); }
-- EDIT --
The OP say
I overlooked an important detail while trying to simplify the problem. I need to pass the objects by reference. So the Ts{} won't work ? What can i do ?
I see... well, I suppose you can (1) create the Ts{} object and store they in a container (a std::tuple seems to me an obvious container) and (2) pass to some_function() the values extracted from the tuple.
The point (1) is simple
std::tuple<Ts...> t { Ts{}... };
The point (2) heavily depend from the list of type (there are repetitions in "type1,type2,...,typeN" ?) and the exact language.
If all types in the list are different and you can use C++14, you can access the tuple values trough std::get<Ts>(t); so the function can be written
template <typename ... Ts>
void repeatOverTypes ()
{
using unused=int[];
std::tuple<Ts...> t { Ts{}... };
(void)unused { 0, (some_function(std::get<Ts>(t)), 0)... };
}
If there are repetitions, you have to access value via integer index, so you have to create a list of index and pass they to an helper function; something like
template <typename T, std::size_t ... Is>
void rotH (T & t, std::index_sequence<Is...> const &)
{
using unused=int[];
(void)unused { 0, (some_function(std::get<Is>(t)), 0)... };
}
template <typename ... Ts>
void repeatOverTypes ()
{
std::tuple<Ts...> t { Ts{}... };
rotH(t, std::make_index_sequence<sizeof...(Ts)>{});
}
Unfortunately std::index_sequence and std::make_index_sequence are introduced in C++14 so, in C++11, you have to simulate they in some way.
As usual in C++17 is simpler; if you are sure (but really, really sure) that types are all different, the function is simply
template <typename ... Ts>
void repeatOverTypes ()
{
std::tuple<Ts...> t { Ts{}... };
(some_function(std::get<Ts>(t)), ...);
}
In case of types collision, with integer sequence,
template <typename T, std::size_t ... Is>
void rotH (T & t, std::index_sequence<Is...> const &)
{ (some_function(std::get<Is>(t)), ...); }
template <typename ... Ts>
void repeatOverTypes ()
{
std::tuple<Ts...> t { Ts{}... };
rotH(t, std::make_index_sequence<sizeof...(Ts)>{});
}
I have a huge list of classes who objects i want to pass to the function one by one
As you seem to need handling many types and avoid to type them out hardcoded in a single place of your code (as provided in this answer), you should consider using dynamic polymorphism, interfaces and self-registering classes rather.
This is a well known technique when a uniform set of operations needs to be done over a lot of specific class types. Many unit testing frameworks use that in order to avoid that additional test cases need to be added at a central place, but just within the translation unit where they're defined.
Here's a sketch (untested) how to implement such:
Provide an interface to describe what needs to be done in some_function() uniquely:
struct IMyInterface {
virtual ~IMyInterface() {}
virtual void WhatNeedsToBeDone() = 0;
virtual int WhatNeedsToBeKnown() const = 0;
};
void some_function(IMyInterface* intf) {
if(intf->WhatNeedsToBeKnown() == 1) {
intf->WhatNeedsToBeDone();
}
}
Provide a singleton registrar keeping a map of functions to create your classes:
class MyRegistrar {
MyRegistrar() {};
using FactoryFunction = std::function<std::unique_ptr<IMyInterface> ()>;
std::map<std::string, FactoryFunction> classFactories;
public:
static MyRegistrar& ClassRegistry() {
static MyRegistrar theRegistrar;
return theRegistrar;
};
template<typename T>
void registerClassFactory(
FactoryFunction factory) {
classFactories[typeid(T).name()] = factory;
};
template<typename T>
std::unique_ptr<IMyInterface> createInstance() {
return classFactories[typeid(T).name()]();
}
template<typename T>
const FactoryFunction& factory() const {
return classFactories[typeid(T).name()];
}
std::vector<FactoryFunction> factories() const {
std::vector<FactoryFunction> result;
for(auto& factory : classFactories) {
result.push_back(factory);
}
return result;
}
};
also provide a registration helper to make it easier registering the types with the global registrar
template<typename T>
struct RegistrationHelper {
RegistrationHelper(
std::function<std::unique_ptr<IMyInterface> ()> factoryFunc =
[](){ return std::make_unique<T>(); }) {
MyRegistrar::ClassRegistry().registerClassFactory<T>(factoryFunc);
}
};
In your specific types you can use that like
class type1 : public IMyInterface {
static RegistrationHelper<type1> reghelper;
public:
void WhatNeedsToBeDone() override {}
int WhatNeedsToBeKnown() const override { return 0; };
};
RegistrationHelper<type1> type1::reghelper;
You can also specialize to deviate from the default factory function:
enum Color { Red, Green };
class type1 : public IMyInterface {
static RegistrationHelper<type1> reghelper;
Color color_;
public:
type1(Color color) : color_(color) {}
void WhatNeedsToBeDone() override {}
int WhatNeedsToBeKnown() const override { return 0; };
};
RegistrationHelper<type1> type1::reghelper(
[](){ return std::make_unique<type1>(condition? Green : Red);
} -> std::function<std::unique_ptr<IMyInterface> ()>
);
To realize your iteration over all classes you can use
for(auto factory : MyRegistrar::ClassRegistry().factories()) {
std::unique_ptr<IMyInterface> intf = factory();
some_function(intf.get());
}

C++11 lambda function as callback and default value

I want to pass a lambda function to another function:
template<typename T>
void test2(T fn){
fn();
}
test2([]{cout<<"Hi"});
But I also want a default empty function in test2. So I do the next:
auto empty_lambda = []{};
template<typename T = decltype(empty_lambda)>
void test(T fn = empty_lambda){
fn();
}
test();
And all good, but I can't put
auto empty_lambda = []{};
inside the class, so I have to keep it in global scope.
Can I improve this somehow? Except option with void test2(){ test2([]{}); }
If it doesn't have to be a lambda, you could more portably use a plain-old static member function:
class foo {
static void do_nothing() {}
public:
template<typename T = decltype(do_nothing)>
void test(T fn = do_nothing){
fn();
}
};
but if you really want lambda syntax, you can take advantage of the implicit conversion to function pointer:
class foo {
public:
template<typename T = void(*)()>
void test(T fn = []{}){
fn();
}
};
RETRACTION: Original answer is non-portable, the standard does not specify that any lambda closure has a literal type so as to be usable in a constant expression.
Believe it or not, you can use auto to declare a static data member (per C++11 §[dcl.spec.auto]/4):
class foo {
static constexpr auto empty_lambda = []{};
public:
template<typename T = decltype(empty_lambda)>
void test(T fn = empty_lambda){
fn();
}
};
constexpr decltype(foo::empty_lambda) foo::empty_lambda;
The definition of the constexpr static data member is - to say the least - messy. (Live code at Coliru).
You can use std::function like following :
class X
{
static std::function<void()> f;
template<typename T = decltype(f)>
void test(T fn = f){
fn();
}
};
std::function<void()> X::f = []{};
See HERE

function pointer to functor

I have a static function foo but the API I want to call only accept pointer to a functor (of similar interface ). Is there a way to pass foo to the API? or I need to re-implement foo in terms of functor.
Example code:
template<typename ReturnType, typename ArgT>
struct Functor: public std::unary_function<ArgT,ReturnType>
{
virtual ~Functor () {}
virtual ReturnType operator()( ArgT) = 0;
};
// I have a pre written function
static int foo (int a) {
return ++a;
}
// I am not allowed to change the signature of this function :(
static void API ( Functor<int,int> * functor ) {
cout << (*functor) (5);
}
int main (void) {
API ( ??? make use of `foo` somehow ??? );
return 0;
}
My question is for calling API, implementing Functor is only solution or there is a way by which I could use foo to pass it to API?
Will boost::bind help here?
I mean boost::bind(foo, _1) will make function object out of foo and then if there is a way to form desired functor out of function object?
It seems like you have no option other than writing your own functor as a derived type of Functor<int, int>. However, you could save yourself some trouble by providing an intermediate class template functor that can be instantiated from a functor or funciton pointer:
template<typename R, typename A>
struct GenericFunctor<R, A> : public Functor<R, A>
{
template <typename F>
MyFunctor(F f) : f_(f) {}
ReturnType operator()(A arg) = { return f_(arg);}
private:
std::function<R(A)> f_; // or boost::function
};
Then you can say
GenericFunctor<int, int> fun = foo;
API(&fun); // works. GenericFinctor<int,int> is a Functor<int,int>
This is just a workaround for the fact that the stuff you have been given is so awful.