473,593 Members | 2,907 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Define a mapping from class types to strings?

Hello world, I'm wondering if it's possible to implement some sort of
class/object that can perform mapping from class types to strings?

I will know the class type at compile time, like so:
const char *s = string_mapper<t hetype>();

However I do not know the string to be associated with the type at
compile time, and will need a way to set up the mapping, to be created
at run time, possibly like so:
void foo(char* some_string_fro m_runtime){
string_mapper_o bj<thetype>.set string(some_str ing_from_runtim e);
}

Possibly I might want to also mix up the string mappings too, haha,
but I suppose I can do that before they even reach the string mapper.

Maybe something crazy like this? Would this work? (I'm purposefully
glossing over the memory management concerns)
template<class T>
const char* string_mapper_b ase(bool set, const char* set_to){
static const char* thestring;
if(set) internal = set_to;
return thestring;
}
template<class T>
inline const char* string_mapper() { return string_mapper_b ase(false,
0);}
template<class T>
inline const char* string_mapper_s et(const char* set_to){return
string_mapper_b ase(true, set_to);}
---
What I'm trying to do is set up a class of objects so that they have a
possibly-user-defined name. All objects will then be able to access
that name and report to the user that their name is so-and-so.

Worse, I would like to keep this open in the future so that new
classes of objects (inherited from a base type) will automatically
have this ability too (so static member data doesn't work too well,
because I'd then have to retype that code - I think?).

Nov 21 '07 #1
5 2565
alan wrote:
Hello world, I'm wondering if it's possible to implement some sort of
class/object that can perform mapping from class types to strings?
Yes, it most certainly is. I would probably use 'typeid' for that.
I will know the class type at compile time, like so:
const char *s = string_mapper<t hetype>();

However I do not know the string to be associated with the type at
compile time, and will need a way to set up the mapping, to be created
at run time, possibly like so:
void foo(char* some_string_fro m_runtime){
string_mapper_o bj<thetype>.set string(some_str ing_from_runtim e);
}
No, you can have your string_mapper template specialised for any of
the involved types. Give them the operator const char* (which will
return the static const pointer) and they should convert very
easily to a char const* like you show.
>
Possibly I might want to also mix up the string mappings too, haha,
but I suppose I can do that before they even reach the string mapper.

Maybe something crazy like this? Would this work? (I'm purposefully
glossing over the memory management concerns)
template<class T>
const char* string_mapper_b ase(bool set, const char* set_to){
static const char* thestring;
if(set) internal = set_to;
return thestring;
}
template<class T>
inline const char* string_mapper() { return string_mapper_b ase(false,
0);}
template<class T>
inline const char* string_mapper_s et(const char* set_to){return
string_mapper_b ase(true, set_to);}
I don't think there is a need to call 'set' here. Just create
a template specialisation for every type you know/can think of.
[..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 21 '07 #2
On Nov 21, 9:30 pm, alan <almkg...@gmail .comwrote:
Hello world, I'm wondering if it's possible to implement some sort of
class/object that can perform mapping from class types to strings?
Dang, is this so simple that it's not even worth a comment? How *is*
this supposed to be done?
>
I will know the class type at compile time, like so:
const char *s = string_mapper<t hetype>();

However I do not know the string to be associated with the type at
compile time, and will need a way to set up the mapping, to be created
at run time, possibly like so:
void foo(char* some_string_fro m_runtime){
string_mapper_o bj<thetype>.set string(some_str ing_from_runtim e);

}

Possibly I might want to also mix up the string mappings too, haha,
but I suppose I can do that before they even reach the string mapper.

Maybe something crazy like this? Would this work? (I'm purposefully
glossing over the memory management concerns)
template<class T>
const char* string_mapper_b ase(bool set, const char* set_to){
static const char* thestring;
if(set) internal = set_to;
return thestring;}

template<class T>
inline const char* string_mapper() { return string_mapper_b ase(false,
0);}
template<class T>
inline const char* string_mapper_s et(const char* set_to){return
string_mapper_b ase(true, set_to);}
The above seems to work, except s/string_mapper_b ase/
string_mapper_b ase<T>/ in the later two functions.

Which then gives me the problem, how can I make a base class such that
it will be able to get the correct string_mapper_b ase<Tfor derived
classes. I think I'll need a helper class that I'll have to
instantiate (possibly by hand, oh well) for each derived class.

Alternatively I might have to just use template classes. Currently
I'm using inheritance from a base object (so that I can have a list of
objects of various classes by simply getting a vector of pointers to
base classes). Could templates be made to work?
Nov 21 '07 #3
On Nov 21, 2:30 pm, alan <almkg...@gmail .comwrote:
Hello world, I'm wondering if it's possible to implement some sort of
class/object that can perform mapping from class types to strings?
I will know the class type at compile time, like so:
const char *s = string_mapper<t hetype>();
Something like typeid(thetype) .name() ?
However I do not know the string to be associated with the
type at compile time,
In which case, you probably want to use std::string, instead of
char const*. This means some sort of map, with the values read
in at runtime. Possibly an std::map< std::type_info const*,
std::string >, but you still have the problem of initialization.

The real question is where the names are coming from: the format
of the source data, and how the type associated with the name is
specified. External files can't contain std::type_info, only
text. And std::type_info: :name() isn't portable (although if
you're only targeting one compiler, and that compiler does
something useful with this function, you may be able to use it).
What you'll probably have to do is define some sort of canonical
name, and map it to the user defined name (using std::map<
std::string, std::string >, for example).
and will need a way to set up the mapping, to be created
at run time, possibly like so:
void foo(char* some_string_fro m_runtime){
string_mapper_o bj<thetype>.set string(some_str ing_from_runtim e);
}
If you can do that, then you can use std::type_info as your key
type in the map. Or rather std::type_info const*, as a
type_info isn't copiable. You'll have to provide a comparison
function, of course, based on type_info::befo re().

I'm rather wondering, however, how you establish the initial
mapping which allows you to call this function.
Possibly I might want to also mix up the string mappings too,
haha, but I suppose I can do that before they even reach the
string mapper.
Maybe something crazy like this? Would this work? (I'm purposefully
glossing over the memory management concerns)
template<class T>
const char* string_mapper_b ase(bool set, const char* set_to){
static const char* thestring;
if(set) internal = set_to;
return thestring;}
I think a class template would be simpler, with two different
functions, and a static class member.
template<class T>
inline const char* string_mapper() { return string_mapper_b ase(false,
0);}
template<class T>
inline const char* string_mapper_s et(const char* set_to){return
string_mapper_b ase(true, set_to);}
---
What I'm trying to do is set up a class of objects so that they have a
possibly-user-defined name. All objects will then be able to access
that name and report to the user that their name is so-and-so.
Worse, I would like to keep this open in the future so that
new classes of objects (inherited from a base type) will
automatically have this ability too (so static member data
doesn't work too well, because I'd then have to retype that
code - I think?).
The static member is in a separate template class, so a new
instance will be created for each instantiation of the template.
The capability is independent of the target class, and will even
work for built-in types.

Something like:

template< typename T >
class StringMapper
{
public:
explicit StringMapper( std::string const& name )
{
ourName = name ;
}

operator std::string() const
{
return ourName ;
}

operator char const*() const
{
return ourName.c_str() ;
}

private:
static std::string ourName ;
} ;

template< typename T >
std::string StringMapper< T >::ourName = std::string() ;

The basic problem remains: how to you find the mapping to start
with.

(I still prefer the solution with std::map, since this allows
you to find the typename of an object, as well as a that of a
statically known type.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 22 '07 #4
On Nov 22, 5:22 pm, James Kanze <james.ka...@gm ail.comwrote:
On Nov 21, 2:30 pm, alan <almkg...@gmail .comwrote:
Hello world, I'm wondering if it's possible to implement some sort of
class/object that can performmappingf rom class types to strings?
I will know the classtypeat compile time, like so:
const char *s = string_mapper<t hetype>();

Something like typeid(thetype) .name() ?
However I do not know the string to be associated with the
typeat compile time,

In which case, you probably want to use std::string, instead of
char const*. This means some sort of map, with the values read
in at runtime. Possibly an std::map< std::type_info const*,
std::string >, but you still have the problem of initialization.

The real question is where the names are coming from: the format
of the source data, and how thetypeassociat ed with the name is
specified. External files can't contain std::type_info, only
text. And std::type_info: :name() isn't portable (although if
you're only targeting one compiler, and that compiler does
something useful with this function, you may be able to use it).
What you'll probably have to do is define some sort of canonical
name, and map it to the user defined name (using std::map<
std::string, std::string >, for example).
From the user, as a string. The class associated to the string is
determined from an object of that class. An object of that class will
provide a method that will allow querying and setting the string.
>
and will need a way to set up themapping, to be created
at run time, possibly like so:
void foo(char* some_string_fro m_runtime){
string_mapper_o bj<thetype>.set string(some_str ing_from_runtim e);
}

If you can do that, then you can use std::type_info as your keytypein the map. Or rather std::type_info const*, as a
type_info isn't copiable. You'll have to provide a comparison
function, of course, based on type_info::befo re().

I'm rather wondering, however, how you establish the initialmappingw hich allows you to call this function.
Possibly I might want to also mix up the string mappings too,
haha, but I suppose I can do that before they even reach the
string mapper.
Maybe something crazy like this? Would this work? (I'm purposefully
glossing over the memory management concerns)
template<class T>
const char* string_mapper_b ase(bool set, const char* set_to){
static const char* thestring;
if(set) internal = set_to;
return thestring;}

I think a class template would be simpler, with two different
functions, and a static class member.
template<class T>
inline const char* string_mapper() { return string_mapper_b ase(false,
0);}
template<class T>
inline const char* string_mapper_s et(const char* set_to){return
string_mapper_b ase(true, set_to);}
---
What I'm trying to do is set up a class of objects so that they have a
possibly-user-defined name. All objects will then be able to access
that name and report to the user that their name is so-and-so.
Worse, I would like to keep this open in the future so that
new classes of objects (inherited from a basetype) will
automatically have this ability too (so static member data
doesn't work too well, because I'd then have to retype that
code - I think?).

The static member is in a separate template class, so a new
instance will be created for each instantiation of the template.
The capability is independent of the target class, and will even
work for built-in types.

Something like:

template< typename T >
class StringMapper
{
public:
explicit StringMapper( std::string const& name )
{
ourName = name ;
}

operator std::string() const
{
return ourName ;
}

operator char const*() const
{
return ourName.c_str() ;
}

private:
static std::string ourName ;
} ;

template< typename T >
std::string StringMapper< T >::ourName = std::string() ;

The basic problem remains: how to you find themappingto start
with.
The user-defined class call name defaults to an empty string.

In the course of the game, when the user picks up an item (generated
by the game) he or she may use a command to call the item, so that all
other items of the same class (generated and not yet generated) will
have the same call name, even if the item is consumed somehow.

So the mapping is created by the item object itself; any object of a
class can change the mapping of that object to the class. And there
will be several classes of that item, each with this ability.

So basically, the item object itself must provide a method that will
change the class name. However, items are passed around as smart
pointers to an abstract base class; therefore, the base class must
itself provide the ability to change the call name.

Here's a solution I've thought up:
template<class T>
//I will use std::string in final code.
const char* string_mapper_b ase(bool set, const char* set_to){
static const char* thestring="";
if(set) internal = set_to;
return thestring;
}

template<class T>
inline const char* string_mapper_g et(){
return string_mapper_b ase<T>(false,0) ;
}
template<class T>
inline const char* string_mapper_s et(const char* set_to){
return string_mapper_b ase<T>(true, set_to);
}
class item{
public:
virtual const char* get_call_name() const=0;
virtual const char* set_call_name(c onst char* c)=0;
virtual void do_action()=0;
virtual void flip_something( )=0;
};

template<class T>
class item_class: public item{
public:
virtual const char* get_call_name() const{
return string_mapper_g et<T>();
}
virtual const char* set_call_name(c onst char* c){
return string_mapper_s et<T>(c);
}
}

class knife: item_class<knif e>{ //works in g++, but not 100% sure if
this is legal
public:
bool dull;
virtual void do_action(){
if(dull){
std::cout <<"Doing an action with a dull
knife!"<<std::e ndl;
} else {
std::cout << "Some nasty slicing action!" <<
std::endl;
}
}
virtual void flip_something( ){
dull = true;
}
}
int
main(){
item *k1 = new knife; //I will use smart pointers in final
code.
item *k2 = new knife;
k2->flip_something ();
k1->do_action();
k2->do_action();
k1->set_call_name( "Some sort of knife");
std::cout << k1->get_call_name( ) << std::endl;
std::cout << k2->get_call_name( ) << std::endl;
k2->set_call_name( "A renamed sort of knife");
std::cout << k1->get_call_name( ) << std::endl;
std::cout << k2->get_call_name( ) << std::endl;
delete: k1; delete k2;
k1->do_action();
k2->do_action();
}

I'm aware that std::string is much superior to char*, but this is just
a test program I hacked together to see if the concept, by itself, was
feasible (it would very well work with integers or bools, for that
matter). I'll use std::string in actual code.

Anyway I'll probably have to define mappings not only to strings, but
also to other data types - for example I'll need a bool that will
inform me if the player has already identified a class of items. This
bool can be queried by any item of that class, and will be set if the
player, for example, reads a scroll of identify and selects any item
of that class; again, any individual object of that class can set the
identified flag, and any individual object of that class must be able
to determine if its class is already identified.

Additionally, I *think* it's possible to put the dorky
string_mapper_b ase() function into the item_class class; the
item_class will simply define a private static string that can be
referred directly by its get_call_name() and set_call_name() methods.

Victor Bazarov wrote:
>Maybe something crazy like this? Would this work? (I'm purposefully
glossing over the memory management concerns)
template<cla ss T>
const char* string_mapper_b ase(bool set, const char* set_to){
static const char* thestring;
if(set) internal = set_to;
return thestring;
}
template<cla ss T>
inline const char* string_mapper() { return string_mapper_b ase(false,
0);}
template<cla ss T>
inline const char* string_mapper_s et(const char* set_to){return
string_mapper_ base(true, set_to);}

I don't think there is a need to call 'set' here. Just create
a template specialisation for every type you know/can think of.
Sorry, but I have two constraints:
1. The string associated with the type must be changeable by the user
at run time.
2. I want to make it easy to add new classes in the future that will
be able to provide this feature without repeating code.

I'll look into the typeid thing; I also need to serialize the data
into a save file, so I'll need a way to map a class name to a unique
string, and a reversed map to associate that unique string to a class
that will generate an item of that class.

Finally, thanks to you both for replies; I was wondering why no one
bothered to reply.
Nov 22 '07 #5
On Nov 22, 7:39 pm, alan <almkg...@gmail .comwrote:
The user-defined class call name defaults to an empty string.

In the course of the game, when the user picks up an item (generated
by the game) he or she may use a command to call the item, so that all
other items of the same class (generated and not yet generated) will
have the same call name, even if the item is consumed somehow.

So the mapping is created by the item object itself; any object of a
class can change the mapping of that object to the class. And there
will be several classes of that item, each with this ability.
Dang; my brain is not working properly. Should be:
So the mapping is created by the item object itself; any object of a
class can change the mapping of that class to any arbitrary string.
And there will be several item classes, each with this ability.
>
So basically, the item object itself must provide a method that will
change the class name. However, items are passed around as smart
pointers to an abstract base class; therefore, the base class must
itself provide the ability to change the call name.

Here's a solution I've thought up:
I have since modified the solution so that the data is privately
stored in the item_class<temp late, although it does require
initializing the static member separately as a template (a little like
in James Kanze's code, except the data member can be mutated by
virtual functions derived from the base class, item, and I don't
create casts to string and const char*).

So I can use this way for both user-called names and in-game
identification; I just have to figure out how to do randomized
appearances properly (like, "puce potion" is a healing_potion in one
game, but sleeping_potion in another). I may have to build an object/
templated object just for randomized appearances.

Nov 22 '07 #6

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

Similar topics

15
1437
by: Tim Henderson | last post by:
Hi i have some errors in my code that i can't find the reason for here is the error i have 3 classes: -Song -Album -Artist Song has 3 pieces of data with getter and setter meathods: -Name | i.e. song name
9
2467
by: Jerry Sievers | last post by:
Fellow Pythonists; I am totally puzzled on the use of slicing on mapping types and especially unsure on use of the Ellipsis... and slicing syntax that has two or more groups seperated by comma. I am referring to (from the manual); Slice objects Slice objects are used to represent slices when extended
0
1590
by: Chris | last post by:
I am using Castor to marshal and unmharshal some objects. I have an object that has a List of strings. I can marshal it without using a mapping file. However, when I try to unmarshal it without using a mapping file, I get an error that the list elements occur more than once. If I use a mapping file and indicate that the data member is a collection, it unmarshals without error. My question is:
2
1515
by: mars | last post by:
Alexandrescu(2000) advance a method about mapping intergral constants to types like this: template<int v> struct Int2Type { enum { value = v }; }; Why cann't use like this: template<int v> struct Int2Type {
2
1894
by: Kenny | last post by:
Can someone point me to details about mapping various MSSQL server data types to C# data types, particular "bit" and timestamp etc. etc. Strings/varchar work fine.. Thanks, KAC -- Kenny A. Chaffin Poet, Engineer, Gun Owner
1
2038
by: yuri | last post by:
Hello, Is it possible to create a binding that would map an input message with a part defined as a complex-type element to a url-encoded string? For example, wsdl file defines a message as <wsdl:message name="MyRequestMsg"> <wsdl:part name="myData" element="req:myData"/> </wsdl:message>
11
2394
by: Frank Silvermann | last post by:
#define q p I must admit to a most elementary confusion. I have only ever used #define to, in point of fact, #redefine . The above is standard. Is the following: #define UNNAMED_OS_32_LEAN_AND_MEAN ? frank --------
20
4023
by: tshad | last post by:
Using VS 2003, I am trying to take a class that I created to create new variable types to handle nulls and track changes to standard variable types. This is for use with database variables. This tells me if a variable has changed, give me the original and current value, and whether the current value and original value is/was null or not. This one works fine but is recreating the same methods over and over for each variable type. ...
13
2716
by: Andreas Eibach | last post by:
Hi, let's say I have this: #include <string.h> #define BLAH "foo" Later on, I do this:
0
7936
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8241
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8366
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8227
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
5738
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5402
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
3853
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
1469
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1203
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.