 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
iwongu Guest
|
Posted: Tue Jun 20, 2006 2:53 pm Post subject: How to get arity from lamda expression? |
|
|
After I learned some Ruby syntax, I could write the code that print
one's tables in a line like the following.
(2..9).each { |i| (1..9).each { |j| puts "#{i}*#{j}=#{i * j}" } }
So, I thought it's good to have something like this in C++.
The written code is this.
----
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace boost::mpl;
class range
{
public:
range() {
}
range(int s, int e) {
s_.push_back(s);
e_.push_back(e);
}
range& operator()(int s, int e) {
s_.push_back(s);
e_.push_back(e);
return *this;
}
template <class F>
range& operator()(F func) {
// now this range only support 2-depth loop.
// but it can be extended.
typedef typename if_c<F::arity == 2, do_2, do_1>::type do_type;
do_type()(s_, e_, func);
return *this;
}
struct do_2
{
void operator()(vector<int>& s_, vector<int>& e_, function<void
(int, int)> func) {
for (int i = s_[0]; i <= e_[0]; ++i)
for (int j = s_[1]; j <= e_[1]; ++j)
func(i, j);
}
};
struct do_1
{
void operator()(vector<int>& s_, vector<int>& e_, function<void
(int)> func) {
for (int i = s_[0]; i <= e_[0]; ++i)
func(i);
}
};
private:
vector<int> s_;
vector<int> e_;
};
With this, I could write the print one's tables code like the
following.
function<void (int, int)> f(cout << _1 << '*' << _2 << '=' << _1 * _2
<< '\n');
range(2, 9)(1, 9)( f );
or
range(2, 9)(1, 9)( function<void (int, int)>(cout << _1 << '*' << _2 <<
'=' << _1 * _2 << '\n' ) );
But What I really want to do is using lamda directly as the parameter
like the below.
range(2, 9)(1, 9)( cout << _1 << '*' << _2 << '=' << _1 * _2 << '\n' );
But I can't find something like ::arity with the lambda expression.
Is there any solution? or is there already some 'range' class like
this?
----
And one more question.
In the documentation of lambda, the 'protect' function is introduced
with sample code.
int x = 1, y = 10;
(_1 + protect(_1 + 2))(x)(y);
But, I can't compile this with g++ 3.2.3.
The following is successfully compiled and the result id 12.
(protect(_1 + 2))(x)(y);
----
I found that the 'function_traits' can not be used with 'function.' I
wish it'll be compatible. :-)
Thanks in advance.
iwongu
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Peter Dimov Guest
|
Posted: Wed Jun 21, 2006 2:54 pm Post subject: Re: How to get arity from lamda expression? |
|
|
iwongu wrote:
| Quote: | After I learned some Ruby syntax, I could write the code that print
one's tables in a line like the following.
(2..9).each { |i| (1..9).each { |j| puts "#{i}*#{j}=#{i * j}" } }
So, I thought it's good to have something like this in C++.
The written code is this.
----
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace boost::mpl;
class range
{
public:
range() {
}
range(int s, int e) {
s_.push_back(s);
e_.push_back(e);
}
range& operator()(int s, int e) {
s_.push_back(s);
e_.push_back(e);
return *this;
}
template <class F
range& operator()(F func) {
// now this range only support 2-depth loop.
// but it can be extended.
typedef typename if_c<F::arity == 2, do_2, do_1>::type do_type;
do_type()(s_, e_, func);
return *this;
}
|
In principle, you don't need F::arity here; s_.size() tells you what to
do. Relying on arity, even if lambda objects did expose one (they don't
because they have a range of arities) would not allow you to express
the equivalent of
(2..9).each { |i| (1..9).each { |j| puts "#{i}" } }
where the arity of the lambda is one, but it is still used in two
nested loops. (This may or may not be valid Ruby code. )
There's the problem of f( i ) not compiling for cout << _2, though; so
you'll need to drop the single dynamically-dimensioned range class and
return range2 or range<2> from operator()( int, int ).
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|