Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

template compilation error to accept different type of lambda/functions

20 views
Skip to first unread message

anhongl...@gmail.com

unread,
Mar 19, 2019, 2:20:41 PM3/19/19
to
Hi Expert,

I am new to C++ and template is d**n hard for me... I am trying to make a class (say Func) to accept different type of lambdas/functions, then I can call it in uniformed way.


Func f([](int a)->bool { return a > 1; }); // lambda with parameter int
Func g([]( )->bool { return true ; }); // lambda without parameter

f.exec(2);
g.exec(2); // the parameter 2 is ignored, always returns true




To do this, I declared class like:


class Func
{
private:
std::function<bool(int)> m_func;

public:
template<typename F> Func(F && f): m_func()
{
if constexpr(std::is_invocable_r_v<bool, F>){
m_func = [f_void = std::function<bool()>(std::forward<F>(f))](int)
{
return f_void();
}
}else{
m_func = std::function<bool(int)>(std::forward<F>(f));
}
}

public:
int exec(int a){ return m_func(a); }
};

my problem is:
1. how to avoid the ctor call of std::function get called in initialization list? It actually has no point since we actually immediately assign the real function to it.

2. this code doesn't compile for VS2017, if fails at else-branch as:

Func f([]()->bool {return false; });
^^^^^^^^^^^^^^^^^^^^^^^^^^^ error C2440: '<function-style-cast>': cannot convert from '_Ty' to 'std::function<bool(int)>'
























anhongl...@gmail.com

unread,
Mar 19, 2019, 2:22:47 PM3/19/19
to
gcc compiles

在 2019年3月19日星期二 UTC-7上午11:20:41,anhongl...@gmail.com写道:

Paavo Helde

unread,
Mar 19, 2019, 4:28:22 PM3/19/19
to
On 19.03.2019 20:20, anhongl...@gmail.com wrote:
> Hi Expert,
>
> I am new to C++ and template is d**n hard for me... I am trying to make a class (say Func) to accept different type of lambdas/functions, then I can call it in uniformed way.
>
>
> Func f([](int a)->bool { return a > 1; }); // lambda with parameter int
> Func g([]( )->bool { return true ; }); // lambda without parameter
>
> f.exec(2);
> g.exec(2); // the parameter 2 is ignored, always returns true
>
>
>
>
> To do this, I declared class like:
>
>
> class Func
> {
> private:
> std::function<bool(int)> m_func;
>
> public:
> template<typename F> Func(F && f): m_func()
> {
> if constexpr(std::is_invocable_r_v<bool, F>){
> m_func = [f_void = std::function<bool()>(std::forward<F>(f))](int)
> {
> return f_void();
> }

A semicolon is missing here.


> }else{
> m_func = std::function<bool(int)>(std::forward<F>(f));
> }
> }
>
> public:
> int exec(int a){ return m_func(a); }
> };
>
> my problem is:
> 1. how to avoid the ctor call of std::function get called in initialization list? It actually has no point since we actually immediately assign the real function to it.
>
> 2. this code doesn't compile for VS2017, if fails at else-branch as:
>
> Func f([]()->bool {return false; });
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error C2440: '<function-style-cast>': cannot convert from '_Ty' to 'std::function<bool(int)>'

After fixing the semicolon, it compiled fine for me.

However, this all seems far too complicated/obfuscated for my taste.
What's wrong with:

#include <functional>
#include <type_traits>

using ftype = std::function<bool(int)>;
using gtype = std::function<bool()>;

class Func {
private:
ftype m_func;
public:
Func(ftype f) : m_func(f) {}
Func(gtype g) : m_func([g](bool dummy) {return g(); }) {}
public:
int exec(int a) { return m_func(a); }
};

int main() {
Func f([](int a)->bool { return a > 1; });
Func g([]()->bool { return true; });

f.exec(2);
g.exec(2); // the parameter 2 is ignored, always returns true
}

What benefit would std::is_invocable_r_v have here over a constructor
overload (other than having fun with impenetrable template syntax, of
course ;-)?



anhongl...@gmail.com

unread,
Mar 19, 2019, 5:08:15 PM3/19/19
to
在 2019年3月19日星期二 UTC-7下午1:28:22,Paavo Helde写道:
Yes, thanks for saving me from the chaos!...
0 new messages