473,406 Members | 2,404 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Metaprogramming question

I want to define a bunch of class like the following.
In general, test<n> have n integer arguments. It has a member function
"doit", which returns

l_i for 0 <= i < l
0 for i == l or 2l + 1
-l_(2n - i) for l+1 <= i < 2l

I'm wondering how to define these test* classes using metaprogramming?
Would you please let me know, if you have any ideas.

Thanks,
Peng

#include <vector>
#include <cassert>
#include <iostream>

class test1{
public:
test1(int l0){
_v.push_back(l0);
}
int doit(int i){
switch(i){
case 0:
return _v[0];
case 1:
return 0;
case 2:
return -_v[0];
case 3:
return 0;
default:
assert(0);
}
}
private:
std::vector<int> _v;
};

class test2{
public:
test2(int l0, int l1){
_v.push_back(l0);
_v.push_back(l1);
}
int doit(int i){
switch(i){
case 0:
return _v[0];
case 1:
return _v[1];
case 2:
return 0;
case 3:
return -_v[1];
case 4:
return -_v[0];
case 5:
return 0;
default:
assert(0);
}
}
private:
std::vector<int> _v;
};

int main(int argc, char *argv[]) {
test1 t1(1);
for(int i = 0; i < 2 * 1 + 2; ++ i){
std::cout << t1.doit(i) << std::endl;
}
test2 t2(1,2);
for(int i = 0; i < 2 * 2 + 2; ++ i){
std::cout << t2.doit(i) << std::endl;
}
}

Oct 24 '05 #1
7 1075

<Pe*******@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
I want to define a bunch of class like the following.
In general, test<n> have n integer arguments. It has a member function
"doit", which returns

l_i for 0 <= i < l
0 for i == l or 2l + 1
-l_(2n - i) for l+1 <= i < 2l

I'm wondering how to define these test* classes using metaprogramming?
Would you please let me know, if you have any ideas.

Thanks,
Peng

#include <vector>
#include <cassert>
#include <iostream>

class test1{
public:
test1(int l0){
_v.push_back(l0);
}
int doit(int i){
switch(i){
case 0:
return _v[0];
case 1:
return 0;
case 2:
return -_v[0];
case 3:
return 0;
default:
assert(0);
}
}
private:
std::vector<int> _v;
};

class test2{
public:
test2(int l0, int l1){
_v.push_back(l0);
_v.push_back(l1);
}
int doit(int i){
switch(i){
case 0:
return _v[0];
case 1:
return _v[1];
case 2:
return 0;
case 3:
return -_v[1];
case 4:
return -_v[0];
case 5:
return 0;
default:
assert(0);
}
}
private:
std::vector<int> _v;
};

int main(int argc, char *argv[]) {
test1 t1(1);
for(int i = 0; i < 2 * 1 + 2; ++ i){
std::cout << t1.doit(i) << std::endl;
}
test2 t2(1,2);
for(int i = 0; i < 2 * 2 + 2; ++ i){
std::cout << t2.doit(i) << std::endl;
}
}


Could you do something like:

template<unsigned int N>
class Test : public Test<N-1>
{
public:
Test<N>( );
Test<N>(int n1)
Test<N>(int n1, int n2)
Test<N>(int n1, int n2, int n3)
etc .
int doit( int n )
{
// some formula...to compute the value....
}
vector<int> _args;

};

// specialization to end the defintion chain.
template<>
class Test<0>
{
int doit( int n );

};
Test<N>(int n1 )
:Test<N-1>( )
{
_args.push_back(n1);
}

Test<N>(int n1 , int n2)
:Test<N-1>(n2)
{
_args.push_back(n2);

}

Test<N>(int n1 , int n2, int n3)
:Test<N-1>(n2,n3 )
{
_args.push_back(n3);

}

As far as I know, there isn't a way to parameterize the number of arguments
for the
template member functions - although there might be something in boost you
could
use. If you have a fairly bounded number for N, you can just enumerate all
possibilities
by including constructors for Test<N> with 0 through N arguments.


Oct 24 '05 #2
Pe*******@gmail.com wrote:
I want to define a bunch of class like the following.
In general, test<n> have n integer arguments. It has a member function
"doit", which returns

l_i for 0 <= i < l
0 for i == l or 2l + 1
-l_(2n - i) for l+1 <= i < 2l

I'm wondering how to define these test* classes using metaprogramming?
Would you please let me know, if you have any ideas.

Thanks,
Peng

#include <vector>
#include <cassert>
#include <iostream>

class test1{
public:
test1(int l0){
_v.push_back(l0);
}
int doit(int i){
switch(i){
case 0:
return _v[0];
case 1:
return 0;
case 2:
return -_v[0];
case 3:
return 0;
default:
assert(0);
}
}
private:
std::vector<int> _v;
};

class test2{
public:
test2(int l0, int l1){
_v.push_back(l0);
_v.push_back(l1);
}
int doit(int i){
switch(i){
case 0:
return _v[0];
case 1:
return _v[1];
case 2:
return 0;
case 3:
return -_v[1];
case 4:
return -_v[0];
case 5:
return 0;
default:
assert(0);
}
}
private:
std::vector<int> _v;
};

int main(int argc, char *argv[]) {
test1 t1(1);
for(int i = 0; i < 2 * 1 + 2; ++ i){
std::cout << t1.doit(i) << std::endl;
}
test2 t2(1,2);
for(int i = 0; i < 2 * 2 + 2; ++ i){
std::cout << t2.doit(i) << std::endl;
}
}


First, please avoid using the lowercase "L" as a variable name or to
differentiate variable names. It's quite confusing to separate 10 from
the l0 for instance. Also I had trouble with these formulas:

-l_(2n - i)
l_i

But based on the program provided I think I figured it out. Anyway, the
following program should be enough to get you started:

template<int N>
struct Integer
{
static const int value = N;
typedef Integer<N+1> next;
};

template <class N, class C >
struct Test
{
static const int value = C::value < N::value ?
C::value :
-1-(2*N::value - C::value);
};

// Integer class is needed for this specialization:
template <int N>
struct Test< Integer<N>, Integer<2*N+1> >
{
static const int value = 0;
};

template <class N>
struct Test<N, N>
{
static const int value = 0;
};

template <class N, class C>
void DoIt( const Test<N, C> )
{
std::cout << Test<N, C>::value << " ";

DoIt( Test<N, typename C::next >() );
}

template <int N>
void DoIt( const Test<Integer<N>, Integer<N*2+1> > )
{
std::cout << Test<Integer<N>, Integer<N*2+1> >::value << " ";
}

int main()
{
DoIt( Test< Integer<1>, Integer<0> >());
std::cout << std::endl;
DoIt( Test< Integer<2>, Integer<0> >());
std::cout << std::endl;
}

Output:
0 0 -1 0
0 1 0 -2 -1 0

Greg

Oct 24 '05 #3

Greg wrote:
Pe*******@gmail.com wrote:
I want to define a bunch of class like the following.
In general, test<n> have n integer arguments. It has a member function
"doit", which returns

l_i for 0 <= i < l
0 for i == l or 2l + 1
-l_(2n - i) for l+1 <= i < 2l

I'm wondering how to define these test* classes using metaprogramming?
Would you please let me know, if you have any ideas.

Thanks,
Peng
.... First, please avoid using the lowercase "L" as a variable name or to
differentiate variable names. It's quite confusing to separate 10 from
the l0 for instance. Also I had trouble with these formulas:

-l_(2n - i)
l_i

But based on the program provided I think I figured it out. Anyway, the
following program should be enough to get you started:

template<int N>
struct Integer
{
static const int value = N;
typedef Integer<N+1> next;
};

template <class N, class C >
struct Test
{
static const int value = C::value < N::value ?
C::value :
-1-(2*N::value - C::value);
};
.... int main()
{
DoIt( Test< Integer<1>, Integer<0> >());
std::cout << std::endl;
DoIt( Test< Integer<2>, Integer<0> >());
std::cout << std::endl;
}

Output:
0 0 -1 0
0 1 0 -2 -1 0

Greg


Of course as soon as I post my program I notice an error. Change:

static const int value = C::value < N::value ?
C::value :
-1-(2*N::value - C::value);

to:

static const int value = C::value < N::value ?
C::value + 1:
-1-(2*N::value - C::value);

for the output:

1 0 -1 0
1 2 0 -2 -1 0

which at least matches the original program's output.

Greg

Oct 24 '05 #4

Dave Townsend wrote:
<Pe*******@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
I want to define a bunch of class like the following.
In general, test<n> have n integer arguments. It has a member function
"doit", which returns

l_i for 0 <= i < l
0 for i == l or 2l + 1
-l_(2n - i) for l+1 <= i < 2l

I'm wondering how to define these test* classes using metaprogramming?
Would you please let me know, if you have any ideas.

Thanks,
Peng

#include <vector>
#include <cassert>
#include <iostream>

class test1{
public:
test1(int l0){
_v.push_back(l0);
}
int doit(int i){
switch(i){
case 0:
return _v[0];
case 1:
return 0;
case 2:
return -_v[0];
case 3:
return 0;
default:
assert(0);
}
}
private:
std::vector<int> _v;
};

class test2{
public:
test2(int l0, int l1){
_v.push_back(l0);
_v.push_back(l1);
}
int doit(int i){
switch(i){
case 0:
return _v[0];
case 1:
return _v[1];
case 2:
return 0;
case 3:
return -_v[1];
case 4:
return -_v[0];
case 5:
return 0;
default:
assert(0);
}
}
private:
std::vector<int> _v;
};

int main(int argc, char *argv[]) {
test1 t1(1);
for(int i = 0; i < 2 * 1 + 2; ++ i){
std::cout << t1.doit(i) << std::endl;
}
test2 t2(1,2);
for(int i = 0; i < 2 * 2 + 2; ++ i){
std::cout << t2.doit(i) << std::endl;
}
}
With Metatemplates this may not be possible..to generate functions with
var args...
U can simply use a single template class with variable no. of args
passed to the constructor.
Could you do something like:

template<unsigned int N>
class Test : public Test<N-1>
{
public:
Test<N>( );
Test<N>(int n1)
Test<N>(int n1, int n2)
Test<N>(int n1, int n2, int n3)
etc .
int doit( int n )
{
// some formula...to compute the value....
}
vector<int> _args;

};

// specialization to end the defintion chain.
template<>
class Test<0>
{
int doit( int n );

};
Test<N>(int n1 )
:Test<N-1>( )
{
_args.push_back(n1);
}

Test<N>(int n1 , int n2)
:Test<N-1>(n2)
{
_args.push_back(n2);

}

Test<N>(int n1 , int n2, int n3)
:Test<N-1>(n2,n3 )
{
_args.push_back(n3);

}

As far as I know, there isn't a way to parameterize the number of arguments
for the
template member functions - although there might be something in boost you
could use. If you have a fairly bounded number for N, you can just enumerate all
possibilities
by including constructors for Test<N> with 0 through N arguments.


Oct 24 '05 #5

"Greg" <gr****@pacbell.net> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Pe*******@gmail.com wrote:
<snip>
First, please avoid using the lowercase "L" as a variable name or to
differentiate variable names. It's quite confusing to separate 10 from
the l0 for instance. Also I had trouble with these formulas:


yessim massa

<snip>
Oct 24 '05 #6

"Dave Townsend" <da********@comcast.net> wrote in message
news:Rd********************@comcast.com...

<Pe*******@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com... <snip>
As far as I know, there isn't a way to parameterize the number of
arguments
for the
template member functions - although there might be something in boost you
could
use. If you have a fairly bounded number for N, you can just enumerate
all
possibilities
by including constructors for Test<N> with 0 through N arguments.


There is a preprocessor extension in boost that you can use to generate code
that is repeatative such as a series of "variable" parameters of some type.
I don't think this is a very efficient method though but it seems it will
get the job done.

http://www.boost.org/libs/preprocessor/doc/index.html

Jon

Oct 24 '05 #7

Jon Slaughter wrote:
"Greg" <gr****@pacbell.net> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Pe*******@gmail.com wrote:


<snip>

First, please avoid using the lowercase "L" as a variable name or to
differentiate variable names. It's quite confusing to separate 10 from
the l0 for instance. Also I had trouble with these formulas:


yessim massa

<snip>


I guess you haven't realized that l's can look like 1's either. Oh
well, someday.
Greg

Oct 25 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Dave | last post by:
Would people agree with the statement that to a large degree, using template metaprogramming techniques turns a C++ compiler into a C++ interpreter (but just for the metaprogrammed portions of the...
9
by: Joe | last post by:
Hi, I found a concept named template metaprogramming that can be used in C+ + code at compile-time. I am a beginner at C++. But I am a programmer on the .NET platform. Do you know if template...
7
by: Joe | last post by:
Hi, I found a concept named template metaprogramming that can be used in C+ + code at compile-time. I am a beginner at C++. But I am a programmer on the .NET platform. Do you know if template...
3
by: stdlib99 | last post by:
Hi, I have a simple question regarding templates and meta programming. I am going to try and work my way through the C++ Template Metaprogramming, a book by David Abrahams and Aleksey...
12
by: nooneinparticular314159 | last post by:
Hello. If I declare the following: template<int a, int b, int SomeArray> class DoSomething{ public: .. .. ..
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.