From: DeMarcus on
Hi,

In C++0x, is lambda the most proper way to initialize a std::function
with a valid function that does nothing?

class SomeClass
{
public:
SomeClass() : fnc_([]{}) {}

private:
std::function<void()> fnc_;
};


Thanks,
Daniel

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On 29 avr, 20:03, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote:
> Hi,
>
> In C++0x, is lambda the most proper way to initialize a std::function
> with a valid function that does nothing?
>
> class SomeClass
> {
> public:
> SomeClass() : fnc_([]{}) {}
>
> private:
> std::function<void()> fnc_;
>
> };

It's a way.
There is no "most proper way".


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 29 Apr., 21:03, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote:
[..]
> In C++0x, is lambda the most proper way to initialize a std::function
> with a valid function that does nothing?
>
> class SomeClass
> {
> public:
> SomeClass() : fnc_([]{}) {}
> private:
> std::function<void()> fnc_;
> };

I'm not sure whether I understand your question correctly:
Is your requirement, that std::function should have a
target?

1) If not, why is the default constructor not OK?
2) If yes, it depends on what the most reasonable
default behaviour is, and that is quite use-case-
dependent. A no-op behaviour is probably a good
initial approach (Null Object Pattern) for many.

Regarding (2) it is also relevant to think of
a user who may want to get the target of the
function (if this becomes available), e.g.

#include <functional>
#include <cassert>

class SomeClass
{
public:
SomeClass() : fnc_(empty_) {}
const std::function<void()>& fnc() const { return fnc_; }
using empty_target_type = void(*)();
static empty_target_type empty() { return empty_; }
private:
static void empty_(){};
std::function<void()> fnc_;
};

int main() {
SomeClass s;
const SomeClass::empty_target_type* ptr =
s.fnc().target<SomeClass::empty_target_type>();
assert(*ptr == SomeClass::empty());
}

is quite easy, but to realize the same thing with a
lambda closure is much harder.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: restor on
> In C++0x, is lambda the most proper way to initialize a std::function
> with a valid function that does nothing?
>
> class SomeClass
> {
> public:
> SomeClass() : fnc_([]{}) {}
>
> private:
> std::function<void()> fnc_;
>
> };

If one of your criteria is for the code to be easily understood by
others, and especially if this problem occurs in more than one place
in the program code, you might consider defining a named function that
does nothing:

void do_nothing(){} //
SomeClass::SomeClass() : fnc(do_nothing) {}

The text "do_nothing" clearly says what is going on. Perhaps getting
used to lambda syntax (at least it tricky corners) requires some time,
but, personally, when I see something like

([]{})

It really makes my brain refuse to work. In C++0x, you could also
write:

{[]{}} or {[](){}} or ([](){})

I realize that this is more a question of personal taste, that's why I
say "you might consider".

Regards,
&rzej


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: DeMarcus on
Daniel Kr�gler wrote:
> On 29 Apr., 21:03, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote:
> [..]
>> In C++0x, is lambda the most proper way to initialize a std::function
>> with a valid function that does nothing?
>>
>> class SomeClass
>> {
>> public:
>> SomeClass() : fnc_([]{}) {}
>> private:
>> std::function<void()> fnc_;
>> };
>
> I'm not sure whether I understand your question correctly:
> Is your requirement, that std::function should have a
> target?
>

fnc_ may or may not be initialized with a proper function in a later
stage, i.e.

void setFnc( std::function<void()> fnc )
{
fnc_ = fnc;
}

I just want to be able to run fnc_() without a crash if it hasn't been
initialized by the user.

> 1) If not, why is the default constructor not OK?

Will the default constructor guarantee me that I can call fnc_ without a
crash?

> 2) If yes, it depends on what the most reasonable
> default behaviour is, and that is quite use-case-
> dependent. A no-op behaviour is probably a good
> initial approach (Null Object Pattern) for many.
>
> Regarding (2) it is also relevant to think of
> a user who may want to get the target of the
> function (if this becomes available), e.g.
>
> #include <functional>
> #include <cassert>
>
> class SomeClass
> {
> public:
> SomeClass() : fnc_(empty_) {}
> const std::function<void()>& fnc() const { return fnc_; }
> using empty_target_type = void(*)();
> static empty_target_type empty() { return empty_; }
> private:
> static void empty_(){};
> std::function<void()> fnc_;
> };
>
> int main() {
> SomeClass s;
> const SomeClass::empty_target_type* ptr =
> s.fnc().target<SomeClass::empty_target_type>();
> assert(*ptr == SomeClass::empty());
> }
>
> is quite easy, but to realize the same thing with a
> lambda closure is much harder.
>

Aha, good point! So comparing different empty functions may not be
trivial. In my particular case I don't need that yet.

Thanks!


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]