From: DeMarcus on
Hi,

I would like to do this.

struct F : public SomeClass
{
void t()
{
int a;

// Set the first lambda.
SomeClass::ssu( [&]() { a = 4711; } );

SomeClass::run( "First", [&]()
{
if( a == 4711 )
std::cout << "Good!" << std::endl;
});
}
};

Is it possible to store the first lambda so an implementation of run()
would look something like this?

SomeClass::run( std::string name, auto lambda )
{
firstLambda_(); // This line is what I don't what it would look like.
std::cout << "Running " << name << std::endl;
lambda();
}

How is a lambda stored so it can be invoked later on? What would an
implementation of SomeClass::ssu() look like?

Thanks,
Daniel



PS. As a side question. If you exchange F for Fixture, t for test and
ssu for setSetup, would above approach be a reasonable way to implement
Test-Driven Development without macros?

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

From: restor on
> I would like to do this.
>
> struct F : public SomeClass
> {
> void t()
> {
> int a;
>
> // Set the first lambda.
> SomeClass::ssu( [&]() { a = 4711; } );
>
> SomeClass::run( "First", [&]()
> {
> if( a == 4711 )
> std::cout << "Good!" << std::endl;
> });
> }
>
> };
>
> Is it possible to store the first lambda so an implementation of run()
> would look something like this?
>
> SomeClass::run( std::string name, auto lambda )
> {
> firstLambda_(); // This line is what I don't what it would look like.
> std::cout << "Running " << name << std::endl;
> lambda();
>
> }
>
> How is a lambda stored so it can be invoked later on? What would an
> implementation of SomeClass::ssu() look like?

Hi, if I undersand your question correctly, you need a generic
function-holder with type erasure. I believe std::function template
would suit your needs:

std::function<void()> callback = [&]{ a = 4711; }; // empty
parentheses not required

But storing a lambda that captures by reference for later is likely to
get you into into the dangling reference trouble.


> PS. As a side question. If you exchange F for Fixture, t for test and
> ssu for setSetup, would above approach be a reasonable way to implement
> Test-Driven Development without macros?

Lambdas have the powerful ability of changing blocks of code and
expressions into objects. Where it can get you is yet unexplored, I
believe. You are likely to have found a very interesting and useful
application. According to my knowlege of unit-testing frameworks
macros are also used to automatically register tests for execution;
i.e. you define and execute test in one "instruction". Would your
example allow that? I believe we already have an "auto-registering"
non-MACRO unit test framework available: TUT (or Template Unit
Testing).

Regards,
&rzej

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

From: Jeffrey Schwab on
On 3/9/10 9:48 PM, DeMarcus wrote:
> Hi,
>
> I would like to do this.
>
> struct F : public SomeClass
> {
> void t()
> {
> int a;
>
> // Set the first lambda.
> SomeClass::ssu( [&]() { a = 4711; } );
>
> SomeClass::run( "First", [&]()
> {
> if( a == 4711 )
> std::cout << "Good!" << std::endl;
> });
> }
> };
>
> Is it possible to store the first lambda so an implementation of run()
> would look something like this?
>
> SomeClass::run( std::string name, auto lambda )
> {
> firstLambda_(); // This line is what I don't what it would look like.
> std::cout << "Running " << name << std::endl;
> lambda();
> }
>
> How is a lambda stored so it can be invoked later on?

Via a wrapper like boost::function (or tr1::function).

> What would an
> implementation of SomeClass::ssu() look like?

http://www.boost.org/doc/libs/1_42_0/doc/html/boost_tr1/subject_list.html#boost_tr1.subject_list.function

typedef boost::function<void ()> nullary_function_t;

class some_t
{
nullary_function_t m_f;
public:

void ssu(nullary_function_t const& f) {
m_f = f;
}
};

> PS. As a side question. If you exchange F for Fixture, t for test and
> ssu for setSetup, would above approach be a reasonable way to implement
> Test-Driven Development without macros?

In my opinion, it is not appropriate for C++. It looks like it is based
on xUnit, but C++ already has "setup" and "tear-down" functions in the
form of constructors and destructors. IME, each test is a either a
class that derives from zero or more fixture base-classes, or else a
function that creates fixtures in automatic storage (and refers to the
fixture members using dot notation, e.g. f.configuration). Setup is
done in the fixture's constructor, and tear-down in the fixture's
destructor. In particular, there is no need to derive your fixtures
from a common base class. If your test-runner needs a homogeneous
collection test functions, then I recommend an STL container of
boost::function objects; each test can then be either a stand-alone
function, or an object defining operator(). If the test objects are
expensive or difficult to copy (e.g. because they derive from
non-trivial fixtures), you can also wrap them with boost::ref.

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