Home > other >  How to properly store lambda functions in a tuple and call them?
How to properly store lambda functions in a tuple and call them?

Time:11-16

I'm trying to create a class that can store functions in a member tuple. But when trying to put lambdas inside of an object's tuple (through function pointers) I'm getting a error. Please explain, what I'm doing wrong and what is the proper way of releasing this idea. I think there should be an elegant and stylistically correct general solution (in terms of functional programming patterns) to avoid boilerplate code in class description, objects creation and filling them with functions.

#include <functional>
#include <string>
#include <iostream>

template<typename... ArgTypes> 
class MyClass {
public:
    //boolean function of some argument
    template<typename Type> using Func = bool(Type const &);

    //type for a tuple of pointers to templated boolean functions
    template<typename... Types> using TupleOfFunctions = typename std::tuple<Func<Types>*...>;
    
    //the tuple
    TupleOfFunctions<ArgTypes...> _tuple;
    
    //constructor
    MyClass(TupleOfFunctions<ArgTypes...> t) : _tuple(t) {  
    }
};

int main(int argc, char** argv) {
    MyClass<int, std::string> M({
        [](int &arg) { return arg > 0; },
        [](std::string &arg) { return arg == "abc"; }
    });
    
    std::cout << (*std::get<0>(M._tuple))(1);
    std::cout << (*std::get<1>(M._tuple))("xyz");
    
    return 0;
}

The error I get is

./test.cpp:26:3: error: no matching function for call to 'MyClass<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::MyClass(<brace-enclosed initializer list>)'
   26 |  });

CodePudding user response:

template<typename Type> using Func = bool(Type const &);

This line suggested functions taking in const type arguments. However:

[](int &arg) { return arg > 0; },
[](std::string &arg) { return arg == "abc"; }

These two lines suggested non-const arguments.

Either remove the const from the first line, or add const to the second two should solve it.

CodePudding user response:

A braced-init-list, like {}, does not actually have a type. In the context of template deduction, you can only use them in certain cases - when deducing against initializer_list (where T is a function template parameter) or when the corresponding parameter is already deduced by something else. In this case, neither of those two things is true - so the compiler cannot figure out what ...ArgTypes is supposed to be.

I think you should use std::make_tuple and store as lambda as function pointer.

Live example

  • Related