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;
}
} 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. 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
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
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.
"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>
"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
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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...
|
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...
|
by: nooneinparticular314159 |
last post by:
Hello. If I declare the following:
template<int a, int b, int SomeArray>
class DoSomething{
public:
..
..
..
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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
|
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,...
|
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...
|
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,...
|
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...
|
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...
|
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,...
|
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...
| |