 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Felipe Magno de Almeida Guest
|
Posted: Wed Sep 15, 2004 11:57 pm Post subject: Template feature |
|
|
is there somehow to make a variable name be a template parameter?
something like this:
template <T>
class Test
{
int T;
};
and then:
int main(void)
{
Test<abc> MyClass;
MyClass.abc = 0;
return 0;
}
Unleast it doesnt compile in my VC++
the message it gives is that abc in the "Test<abc> MyClass" line isnt
defined.
There is other way to make this?
Thanks in advance.
--
Felipe Magno de Almeida
Ciencia da Computacao - Unicamp
[email]felipe.almeida (AT) ic (DOT) unicamp.br[/email] - UIN: 2113442
Cause Rock and Roll can never die.
"if you want to learn something really well, teach it to a computer."
What is Communism?
Answer: "Communism is the doctrine of the conditions of the liberation
of the proletariat." (by Karl Marx)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alberto Barbati Guest
|
Posted: Thu Sep 16, 2004 11:05 am Post subject: Re: Template feature |
|
|
Felipe Magno de Almeida wrote:
| Quote: | is there somehow to make a variable name be a template parameter?
|
That's not possible. Template parameters can be:
1) types
2) non-types such as integer, enumeration, pointers or references
3) templates
"names" cannot be used as template parameters. If you have this kind of
doubts I suggest reading a good book about templates, for example "C++
Templates: The complete guide" by Vandevoorde and Josuttis.
| Quote: | There is other way to make this?
|
The only way is by using macro preprocessing, but I wouldn't suggest
that if you care about code readability.
Alberto
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jonathan Turkanis Guest
|
Posted: Thu Sep 16, 2004 11:18 am Post subject: Re: Template feature |
|
|
"Felipe Magno de Almeida" <felipe.almeida (AT) ic (DOT) unicamp.br> wrote:
| Quote: | is there somehow to make a variable name be a template parameter?
something like this:
template <T
class Test
{
int T;
};
and then:
int main(void)
{
Test
MyClass.abc = 0;
return 0;
}
|
The short answer is no. Below, for fun, I'll suggest three ways to approximate
the above syntax. However, I'm sure they won't satisfy you, and I don't
recommend you actually use them.
The real clue that you are doing something wrong is the template declaration:
template<T>
class Test;
A template parameter must be delared as a type, non-type or template. E.g.
template<typename T>
class Test;
template<int T>
class Test;
template< template
class Test;
You've done none of these. You seem to want to be able to do this:
template<identifier T>
class Test
{
int T;
};
But the language doesn't allow this. Macros are the principle language
constructs which can take identifiers as arguments (See method #3, below).
So, let me ask, what problem are you trying to solve?
Now, for fun.
------------------------------
Method #1. Use enumerators for variable names, and operator[] instead of
operator. ("operator dot"):
enum varname {
cat, dog, ant, rat, horse
};
template<varname Name>
class MyClass {
public:
int& operator[] (varname name)
{
assert(Name == name);
return n;
}
const int& operator[] (varname name) const
{
assert(Name == name);
return n;
}
private:
int n;
};
int main()
{
MyClass<cat> c1;
c1[cat] = 0;
// print value of cat variable:
std::cout << c1[cat] << "n";
// Attempt to access non-existing variable:
c1[rat] = 0; // Assertion failure.
MyClass
c2[horse] = 6;
etc.
}
------------------------------
Method #2. Use c-style strings with external linkage for variable names:
template<const char* Name>
class MyClass2 {
public:
int& operator[] (const char* name)
{
assert(strcmp(Name, name) == 0);
return n;
}
const int& operator[] (const char* name) const
{
assert(strcmp(Name, name) == 0);
return n;
}
private:
int n;
};
extern const char cat[] = "cat";
extern const char dog[] = "dog";
extern const char ant[] = "ant";
extern const char rat[] = "rat";
extern const char horse[] = "horse";
int main()
{
MyClass<cat> c1;
c1[cat] = 0;
// or: c1["cat"] = 0;
// print value of cat variable:
std::cout << c1["cat"] << "n";
// Attempt to access non-existing variable:
c1["sloth"] = 0; // Assertion failure.
MyClass
c2["horse"] = 6;
etc.
}
------------------------------
Method #3. Macros
#define DEFINE_MYCLASS(varname)
struct MyClass_##varname { int varname; };
#define MYCLASS(varname) MyClass_##varname
DEFINE_MYCLASS(cat)
DEFINE_MYCLASS(dog)
int main()
{
MYCLASS(cat) c1;
c1.cat = 0;
std::cout << c1.cat << "n"; // prints '0'
//c1.rat = 0; // Error!
MYCLASS(dog) c2;
c2.dog = 6;
etc.
}
------------------------
Jonathan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jakacki Guest
|
Posted: Thu Sep 16, 2004 11:21 am Post subject: Re: Template feature |
|
|
| Quote: | is there somehow to make a variable name be a template
parameter? something like this:
template <T
class Test
{
int T;
};
and then:
int main(void)
{
Test
MyClass.abc = 0;
return 0;
}
|
No, but you can create "data" class:
template <class Tag>
struct Data { int d; };
and "variable names" classes:
struct abc;
struct foo;
then build your class from "data" classes:
class Test : public Data<abc>, public Data<foo>
{
};
and "write/read" your "variables" like this:
Test t;
(Data<abc>&)(t).d = 1;
cout << (Data
Syntax can be made nicer, see Andrei Alexandrescu's "Modern C++ Design"
for more details.
BR
Grzegorz
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Michiel Salters Guest
|
Posted: Fri Sep 17, 2004 2:00 am Post subject: Re: Template feature |
|
|
Felipe Magno de Almeida <felipe.almeida (AT) ic (DOT) unicamp.br> wrote
| Quote: | is there somehow to make a variable name be a template parameter?
something like this:
template <T
class Test
{
int T;
};
and then:
int main(void)
{
Test
MyClass.abc = 0;
return 0;
}
|
Yes, with some problems (on older compilers)
template< template < typename > B >
class Test : public B < int >
{
}
template< typename T >
struct Member_abc {
T abc;
}
Test<Member_abc> MyObject;
MyObject.abc = 0;
Regards,
Michiel Salters
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Felipe Magno de Almeida Guest
|
Posted: Fri Sep 17, 2004 2:18 am Post subject: Re: Template feature |
|
|
| Quote: | Syntax can be made nicer, see Andrei Alexandrescu's "Modern C++ Design"
for more details.
|
That's the one I'm reading.
--
Felipe Magno de Almeida
Ciencia da Computacao - Unicamp
[email]felipe.almeida (AT) ic (DOT) unicamp.br[/email] - UIN: 2113442
Cause Rock and Roll can never die.
"if you want to learn something really well, teach it to a computer."
What is Communism?
Answer: "Communism is the doctrine of the conditions of the liberation
of the proletariat." (by Karl Marx)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Felipe Magno de Almeida Guest
|
Posted: Fri Sep 17, 2004 2:21 am Post subject: Re: Template feature |
|
|
Alberto Barbati wrote:
| Quote: | Felipe Magno de Almeida wrote:
is there somehow to make a variable name be a template parameter?
1) types
2) non-types such as integer, enumeration, pointers or references
enumaration isnt considered a type? or you mean an instance of an |
enumaration;
--
Felipe Magno de Almeida
Ciencia da Computacao - Unicamp
[email]felipe.almeida (AT) ic (DOT) unicamp.br[/email] - UIN: 2113442
Cause Rock and Roll can never die.
"if you want to learn something really well, teach it to a computer."
What is Communism?
Answer: "Communism is the doctrine of the conditions of the liberation
of the proletariat." (by Karl Marx)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Fri Sep 17, 2004 2:24 am Post subject: Re: Template feature |
|
|
In article <Chc2d.5365$2T6.169569 (AT) twister1 (DOT) libero.it>, Alberto Barbati
<AlbertoBarbati (AT) libero (DOT) it> writes
| Quote: | Felipe Magno de Almeida wrote:
is there somehow to make a variable name be a template parameter?
That's not possible. Template parameters can be:
1) types
OK
2) non-types such as integer, enumeration, pointers or references
But a reference is a type and I think you meant values of integer type, |
enumeration type and pointer type for the rest.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Terje Slettebų Guest
|
Posted: Fri Sep 17, 2004 3:02 am Post subject: Re: Template feature |
|
|
"Felipe Magno de Almeida" <felipe.almeida (AT) ic (DOT) unicamp.br> wrote
| Quote: | is there somehow to make a variable name be a template parameter?
something like this:
template <T
class Test
{
int T;
};
and then:
int main(void)
{
Test
MyClass.abc = 0;
return 0;
}
|
In addition to the suggestions given by the other posters, you might try
tuples in combination with enum, not at least if you want to access more
than one element:
#include <iostream>
#include <string>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
int main()
{
enum { abc, def, ghi };
boost::tuple<int,double,std::string> value;
value.get<abc>()=123;
value.get<def>()=1.23;
value.get<ghi>()="Test";
std::cout << value << "n";
}
This prints: "(123 1.23 Test)"
Regards,
Terje
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Fri Sep 17, 2004 10:58 am Post subject: Re: Template feature |
|
|
Felipe Magno de Almeida <felipe.almeida (AT) ic (DOT) unicamp.br> wrote:
| Quote: | is there somehow to make a variable name be a template parameter?
something like this:
template <T
class Test
{
int T;
};
and then:
int main(void)
{
Test
MyClass.abc = 0;
return 0;
}
Unleast it doesnt compile in my VC++
the message it gives is that abc in the "Test<abc> MyClass" line isnt
defined.
There is other way to make this?
|
It could be helpful if you elaborated what you need this for.
Meanwhile, I've sketched for fun some machinery to allow for the following
syntax:
struct a {};
struct b {};
struct c {};
struct with_named_members
: members_as_hierarchy<mpl::vector<
named_member
, named_member<b, int>
, named_member<c, double>
};
int main(int ac, char** av)
{
with_named_members t;
std::cout
<< typeid(t.member
<< typeid(t.member
<< typeid(t.member
;
t.member
t.member<b>() = 0xdead;
t.member<c>() = 22/7.0;
}
If it suffices, here is the machinery:
#include "boost/mpl/identity.hpp"
#include "boost/mpl/fold.hpp"
#include "boost/mpl/find_if.hpp"
#include "boost/mpl/same_as.hpp"
#include "boost/mpl/vector.hpp"
#include "boost/mpl/deref.hpp"
namespace mpl = boost::mpl;
template<class Name, class T>
struct named_member
{
typedef Name name;
typedef T type;
};
namespace aux
{
class named_member_base
{
private:
struct no;
protected:
~named_member_base() {}
public:
void member(mpl::identity<no>);
};
struct make_hierarchy_unit
{
template<class T, class Member> struct apply
{
struct type : T
{
using T::member;
typename Member::type& member(mpl::identity<typename
Member::name>) { return member_; }
typename Member::type member_;
};
};
};
template<class Name>
struct same_name
{
template<class T> struct apply : mpl::same_as<Name>::template
apply<typename T::name>
{};
};
} // namespace aux
template<class MemberSeq>
struct members_as_hierarchy
{
class type : mpl::fold<MemberSeq, aux::named_member_base,
aux::make_hierarchy_unit>::type
{
private:
typedef typename mpl::fold<MemberSeq, aux::named_member_base,
aux::make_hierarchy_unit>::type base;
template<class Name> struct type_by_name
{
typedef typename mpl::deref<typename
mpl::find_if::type>::type t;
typedef typename t::type type;
};
public:
template<class Name>
typename type_by_name<Name>::type& member()
{
return this->base::member(mpl::identity<Name>());
}
};
};
--
Maxim Yegorushkin
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alberto Barbati Guest
|
Posted: Fri Sep 17, 2004 5:33 pm Post subject: Re: Template feature |
|
|
Francis Glassborow wrote:
| Quote: | In article <Chc2d.5365$2T6.169569 (AT) twister1 (DOT) libero.it>, Alberto Barbati
[email]AlbertoBarbati (AT) libero (DOT) it[/email]> writes
2) non-types such as integer, enumeration, pointers or references
But a reference is a type and I think you meant values of integer type,
enumeration type and pointer type for the rest.
|
Sure. I thought it should have been clear from the context, but clearly
it wasn't. Thanks for pointing that out.
Alberto
[ 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
|
|