Prev: I keep running into long term c++ programmers who refuse to use exceptions
Next: filtering (a view on) an STL container
From: DeMarcus on 9 Mar 2010 09:48 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 9 Mar 2010 22:43 > 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 9 Mar 2010 22:46
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! ] |