[Lambda] Help with if_then_else
Consider this (working) code using Boost.FileSystem:
fs::directory_iterator di(dir);
fs::directory_iterator end;
while (di != end) {
if (is_directory(*di)) cout << "D\n";
else cout << "~D\n";
++di;
}
This looks like it should be lambda-able. Here's my attempt:
for_each(fs::directory_iterator(dir), fs::directory_iterator(),
if_then_else(bind(&fs::is_directory, _1),
cout << "D\n",
cout << "~D\n"));
VC7.1 doesn't like this -- the diagnostics are below. Any idea how I can make
this work?
Thanks,
Scott
fs.cpp(39) : error C2784: 'const
boost::lambda::lambda_functor
On Mar 8, 2006, at 3:21 PM, Scott Meyers wrote:
Consider this (working) code using Boost.FileSystem:
fs::directory_iterator di(dir); fs::directory_iterator end; while (di != end) { if (is_directory(*di)) cout << "D\n"; else cout << "~D\n"; ++di; }
This looks like it should be lambda-able. Here's my attempt:
for_each(fs::directory_iterator(dir), fs::directory_iterator(), if_then_else(bind(&fs::is_directory, _1), cout << "D\n", cout << "~D\n"));
VC7.1 doesn't like this -- the diagnostics are below. Any idea how I can make this work?
I can spot one thing at least: Arguments to if_then_else must be lambda functions:
if_then_else(bind(&fs::is_directory, _1), var(cout) << "D\n", var(cout) << "~D\n"));
This delays the evaluation of the branches (which would otherwise just print D or ~D once, when the lambda function is created, rather than during every iteration of for_each Best, Jaakko
On 3/8/06, Scott Meyers
This looks like it should be lambda-able. Here's my attempt:
for_each(fs::directory_iterator(dir), fs::directory_iterator(), if_then_else(bind(&fs::is_directory, _1), cout << "D\n", cout << "~D\n"));
VC7.1 doesn't like this -- the diagnostics are below. Any idea how I can make this work?
Try out: for_each(fs::directory_iterator(dir), fs::directory_iterator(), if_then_else(bind(&fs::is_directory, _1), cout << constant("D\n"), cout << constant("~D\n"))); The problem is that 'cout << "D\n"' is getting called immediately - as it's not a lambda expression, by making "D\n" a delayed constant it becomes one. This is documented at http://tinyurl.com/7jq3v. Hope that helps, Daniel
Scott Meyers wrote:
Consider this (working) code using Boost.FileSystem:
fs::directory_iterator di(dir); fs::directory_iterator end; while (di != end) { if (is_directory(*di)) cout << "D\n"; else cout << "~D\n"; ++di; }
This looks like it should be lambda-able. Here's my attempt:
for_each(fs::directory_iterator(dir), fs::directory_iterator(), if_then_else(bind(&fs::is_directory, _1), cout << "D\n", cout << "~D\n"));
VC7.1 doesn't like this -- the diagnostics are below. Any idea how I can make this work?
The cout << "D\n" subexpression is evaluated immediately since it doesn't have any lambda components. Use var(cout) << "D\n" instead, or the ?: variant: cout << if_then_else_return( bind(&fs::is_directory, _1), "D\n", "~D\n" ) You could also make an alias for var(std::cout): var_typestd::ostream::type cout = var( std::cout ); and use that in the lambda expressions.
I tried both suggested solutions (applying var to cout, applying constant to the output string -- see below), but neither works. What follows is a complete compilation unit (not program -- there's no main) that fails with both VC7.1 and gcc 3.4.2 when I uncomment either of the two for_each loops. The error messages are, um, not as enlightening as they might be. Any suggestions how to get this to work? Thanks, Scott #include <iostream> #include <string> #include "boost/filesystem/operations.hpp" #include "boost/filesystem/path.hpp" #include "boost/lambda/bind.hpp" #include "boost/lambda/if.hpp" void f(const std::string& dirName) { using namespace std; namespace fs = boost::filesystem; fs::path dir(dirName, fs::native); using namespace boost::lambda; // for_each(fs::directory_iterator(dir), fs::directory_iterator(), // if_then_else(bind(&fs::is_directory, _1), // cout << constant("D\n"), // cout << constant("~D\n"))); // for_each(fs::directory_iterator(dir), fs::directory_iterator(), // if_then_else(bind(&fs::is_directory, _1), // var(cout) << "D\n", // var(cout) << "~D\n")); }
On 3/8/06, Scott Meyers
The error messages are, um, not as enlightening as they might be. Any suggestions how to get this to work?
Thanks,
Scott
#include <iostream> #include <string> #include "boost/filesystem/operations.hpp" #include "boost/filesystem/path.hpp" #include "boost/lambda/bind.hpp" #include "boost/lambda/if.hpp"
You also need to include "boost/lambda/lambda.hpp", to declare operator<<. Daniel
participants (4)
-
Daniel James
-
Jaakko Jarvi
-
Peter Dimov
-
Scott Meyers