473,385 Members | 1,344 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,385 software developers and data experts.

How to make code accepting differet types work?

This is something I've been thinking about creating, and am trying to get
the pieces together.

I want to be able to assign values in a method accepting different types.
I.E.

MyInstance.MyMethod("IntField") = 1;
MyInstance.MyMethod("FloatField") = 2.34f;
MyInstance.MyMethod("StringField") = std::string("Hello");

Is this possible?

I know I could do it using function overloading by passing the parms, I.E.

MyInstance.MyMethod("IntField", 1);
MyInstance.MyMethod("FloatField", 2.34f);
MyInstance.MyMethod("StringField", std::string("Hello");

I'm thinking to use the assignment I would need to return a LHV, a reference
to what was being assigned. I think I just answered my own question.
Whatever I am returning would need to have operator=() overloaded for each
type.

Is this the way to go?
Jul 12 '06 #1
9 1381
Jim Langston wrote:
This is something I've been thinking about creating, and am trying to get
the pieces together.

I want to be able to assign values in a method accepting different types.
I.E.

MyInstance.MyMethod("IntField") = 1;
MyInstance.MyMethod("FloatField") = 2.34f;
MyInstance.MyMethod("StringField") = std::string("Hello");

Is this possible?

I know I could do it using function overloading by passing the parms, I.E.

MyInstance.MyMethod("IntField", 1);
MyInstance.MyMethod("FloatField", 2.34f);
MyInstance.MyMethod("StringField", std::string("Hello");

I'm thinking to use the assignment I would need to return a LHV, a reference
to what was being assigned. I think I just answered my own question.
Whatever I am returning would need to have operator=() overloaded for each
type.

Is this the way to go?

Why do the functions need to have the same name? A far more
conventional approach would be, e.g.,

MyInstance.IntField() = 1;
MyInstance.FloatField() = 2.34;
etc.

with corresponding fcn declarations:
int& IntField();
float& FloatField();
etc.

Style-conscious folk would probably go with the even more conventional
approach of setter functions:

void setIntField(int i);
void setFloatField(float f);

Jul 12 '06 #2
"Mark P" <us****@fall2005REMOVE.fastmailCAPS.fmwrote in message
news:%i*********************@newssvr13.news.prodig y.com...
Jim Langston wrote:
>This is something I've been thinking about creating, and am trying to get
the pieces together.

I want to be able to assign values in a method accepting different types.
I.E.

MyInstance.MyMethod("IntField") = 1;
MyInstance.MyMethod("FloatField") = 2.34f;
MyInstance.MyMethod("StringField") = std::string("Hello");

Is this possible?

I know I could do it using function overloading by passing the parms,
I.E.

MyInstance.MyMethod("IntField", 1);
MyInstance.MyMethod("FloatField", 2.34f);
MyInstance.MyMethod("StringField", std::string("Hello");

I'm thinking to use the assignment I would need to return a LHV, a
reference to what was being assigned. I think I just answered my own
question. Whatever I am returning would need to have operator=()
overloaded for each type.

Is this the way to go?

Why do the functions need to have the same name? A far more conventional
approach would be, e.g.,

MyInstance.IntField() = 1;
MyInstance.FloatField() = 2.34;
etc.

with corresponding fcn declarations:
int& IntField();
float& FloatField();
etc.

Style-conscious folk would probably go with the even more conventional
approach of setter functions:

void setIntField(int i);
void setFloatField(float f);
Yes, normally it would, but I plan on using this to assign values to a SQL
table where the string value will be a key into the field name. Keeping the
method names the same would simplify the interface for the end user (who
will probably remain me). So I could do something like:

DynSQL PlayerTable( ServerConnInfo, "Player" );
PlayerTable.reset();
PlayerTable.SetField("Name") = Player.Name;
PlayerTable.SetField("Age") = Player.Age;
PlayerTable.SetField("Sex") = Player.Sex;
PlayerTable.SetField("Strength") = Player.Str;
std::string Result = PlayerTable.insert();

So that the user doesn't have to care what types the variables are, only
have to know their names. This makes it easier for some tables such as my
item table that has 47+ fields.
Jul 12 '06 #3
In article <i0***************@fe07.lga>,
"Jim Langston" <ta*******@rocketmail.comwrote:
This is something I've been thinking about creating, and am trying to get
the pieces together.

I want to be able to assign values in a method accepting different types.
I.E.

MyInstance.MyMethod("IntField") = 1;
MyInstance.MyMethod("FloatField") = 2.34f;
MyInstance.MyMethod("StringField") = std::string("Hello");

Is this possible?

I know I could do it using function overloading by passing the parms, I.E.

MyInstance.MyMethod("IntField", 1);
MyInstance.MyMethod("FloatField", 2.34f);
MyInstance.MyMethod("StringField", std::string("Hello");

I'm thinking to use the assignment I would need to return a LHV, a reference
to what was being assigned. I think I just answered my own question.
Whatever I am returning would need to have operator=() overloaded for each
type.

Is this the way to go?
There are a couple of ways to handle this.

(1) You can convert everything to a single standard type before putting
them in the MyInstance object (you mentioned in a latter post about SQL,
so converting everything to strings before putting them in would work.)
Boost's lexical_cast works well for this.

class MyClass {
public:
template < typename T >
void MyMethod( T value ) {
string s = lexical_cast<string>( value );
// do stuff with s
}
};

(2) You can use the same method that the iostream classes use. Overload
MyMethod for all of the basic types, and provide a mechanism for
allowing class developers to make custom functions.

(3) You might also be able to use Boost's "Any" type depending on the
situation.
Jul 12 '06 #4
Jim Langston wrote:
This is something I've been thinking about creating, and am trying to get
the pieces together.

I want to be able to assign values in a method accepting different types.
I.E.

MyInstance.MyMethod("IntField") = 1;
MyInstance.MyMethod("FloatField") = 2.34f;
MyInstance.MyMethod("StringField") = std::string("Hello");

Is this possible?
Assign to what?

Could you use a map and have something like MyInstance["IntField"] = 1?

--
Ian Collins.
Jul 12 '06 #5
"Ian Collins" <ia******@hotmail.comwrote in message
news:4h*************@individual.net...
Jim Langston wrote:
>This is something I've been thinking about creating, and am trying to get
the pieces together.

I want to be able to assign values in a method accepting different types.
I.E.

MyInstance.MyMethod("IntField") = 1;
MyInstance.MyMethod("FloatField") = 2.34f;
MyInstance.MyMethod("StringField") = std::string("Hello");

Is this possible?
Assign to what?

Could you use a map and have something like MyInstance["IntField"] = 1?
MyInstance will, in fact, have a map, but the values will be std::string.
If I was using method overloading it would be something like (untested
code):

void MyInstance::MyMethod( std::string key, int value )
{
std::map<std::string, std::string>::iterator it = MyMap.find(key);
if ( it != MyMap.end() )
it.second = jml::StrmConvert( value );
}

StrmConvert is a template that uses stringstream to convert between types,
in this case to a std::string.

Yes, I know I can actually use this, but I would prefer to use operator= as
it just seems more natural to me.
Jul 12 '06 #6
Jim Langston wrote:
"Ian Collins" <ia******@hotmail.comwrote in message
news:4h*************@individual.net...
>Jim Langston wrote:
>>This is something I've been thinking about creating, and am trying
to get the pieces together.

I want to be able to assign values in a method accepting different
types. I.E.

MyInstance.MyMethod("IntField") = 1;
MyInstance.MyMethod("FloatField") = 2.34f;
MyInstance.MyMethod("StringField") = std::string("Hello");

Is this possible?
Assign to what?

Could you use a map and have something like MyInstance["IntField"] =
1?

MyInstance will, in fact, have a map, but the values will be
std::string. If I was using method overloading it would be something
like (untested code):

void MyInstance::MyMethod( std::string key, int value )
{
std::map<std::string, std::string>::iterator it = MyMap.find(key);
if ( it != MyMap.end() )
it.second = jml::StrmConvert( value );
}

StrmConvert is a template that uses stringstream to convert between
types, in this case to a std::string.

Yes, I know I can actually use this, but I would prefer to use
operator= as it just seems more natural to me.
I didn't see the beginning of the conversation, but here is my take on
what you're asking about (as I understand it):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
#include <string>
#include <map>

class MyClass {
std::map<std::string,inti;
std::map<std::string,floatf;
std::map<std::string,std::stringstr;
public:
class MyProxy {
MyClass& mc;
std::string key;
public:
MyProxy(MyClass& m, std::string const& k) : mc(m), key(k) {}
void operator =(int i) { mc.i[key] = i; }
void operator =(float f) { mc.f[key] = f; }
void operator =(std::string const &s) { mc.str[key] = s; }
};

MyProxy MyMethod(std::string const& k) {
return MyProxy(*this,k);
}
};

int main() {
MyClass MyInstance;
MyInstance.MyMethod("OneInt") = 0;
MyInstance.MyMethod("TwoInt") = 42;
MyInstance.MyMethod("OneFloat") = 1.0f;
MyInstance.MyMethod("TwoFloat") = 3.14159f;
MyInstance.MyMethod("OneString") = "blah";
MyInstance.MyMethod("TwoString") = "blahblah";
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~

Enjoy!

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 12 '06 #7

Victor Bazarov wrote:
Jim Langston wrote:
"Ian Collins" <ia******@hotmail.comwrote in message
news:4h*************@individual.net...
Jim Langston wrote:
This is something I've been thinking about creating, and am trying
to get the pieces together.

I want to be able to assign values in a method accepting different
types. I.E.

MyInstance.MyMethod("IntField") = 1;
MyInstance.MyMethod("FloatField") = 2.34f;
MyInstance.MyMethod("StringField") = std::string("Hello");

Is this possible?

Assign to what?

Could you use a map and have something like MyInstance["IntField"] =
1?
MyInstance will, in fact, have a map, but the values will be
std::string. If I was using method overloading it would be something
like (untested code):

void MyInstance::MyMethod( std::string key, int value )
{
std::map<std::string, std::string>::iterator it = MyMap.find(key);
if ( it != MyMap.end() )
it.second = jml::StrmConvert( value );
}

StrmConvert is a template that uses stringstream to convert between
types, in this case to a std::string.

Yes, I know I can actually use this, but I would prefer to use
operator= as it just seems more natural to me.

I didn't see the beginning of the conversation, but here is my take on
what you're asking about (as I understand it):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
#include <string>
#include <map>

class MyClass {
std::map<std::string,inti;
std::map<std::string,floatf;
std::map<std::string,std::stringstr;
public:
class MyProxy {
MyClass& mc;
std::string key;
public:
MyProxy(MyClass& m, std::string const& k) : mc(m), key(k) {}
void operator =(int i) { mc.i[key] = i; }
void operator =(float f) { mc.f[key] = f; }
void operator =(std::string const &s) { mc.str[key] = s; }
};

MyProxy MyMethod(std::string const& k) {
return MyProxy(*this,k);
}
};

int main() {
MyClass MyInstance;
MyInstance.MyMethod("OneInt") = 0;
MyInstance.MyMethod("TwoInt") = 42;
MyInstance.MyMethod("OneFloat") = 1.0f;
MyInstance.MyMethod("TwoFloat") = 3.14159f;
MyInstance.MyMethod("OneString") = "blah";
MyInstance.MyMethod("TwoString") = "blahblah";
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~

Enjoy!
Such a class would not be extensible though. An extensible version
would use templates and an "any" type class. Any type you wanted to
support would have to be registered but you'd be able to register more
types without modifying existing code.

A possible solution is a getMap<T>() function that is overloaded for
every map you support. Or you can have a single map to an "any" type
(which avoids the problem that having multiple maps would allow you to
reuse names as long as they were different types).

Once again you use overloaded functions to determine how the data is
actually stored.

Generally I solve this problem by not using an "any" class but instead
have an "opaque" class which is simply binary data, and then overloaded
converter functions You can also make each type registered with some
enumeration to check compatibility. It does rely on anything you want
to store having conversions to and from an opaque.

Jul 12 '06 #8

"Jim Langston" <ta*******@rocketmail.comwrote in message
news:i0***************@fe07.lga...
This is something I've been thinking about creating, and am trying to get
the pieces together.

I want to be able to assign values in a method accepting different types.
I.E.

MyInstance.MyMethod("IntField") = 1;
MyInstance.MyMethod("FloatField") = 2.34f;
MyInstance.MyMethod("StringField") = std::string("Hello");

Is this possible?

I know I could do it using function overloading by passing the parms, I.E.

MyInstance.MyMethod("IntField", 1);
MyInstance.MyMethod("FloatField", 2.34f);
MyInstance.MyMethod("StringField", std::string("Hello");

I'm thinking to use the assignment I would need to return a LHV, a
reference to what was being assigned. I think I just answered my own
question. Whatever I am returning would need to have operator=()
overloaded for each type.

Is this the way to go?
Thank you everyone for your input. This is what I have settled on.

Comments welcome. Except for people saying I shouldn't preceed my class
names with "C".

#include <string>
#include <map>
#include <sstream>
#include <iostream>

template<typename T, typename F T StrmConvert( F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >to;
return to;
}

template<typename Fstd::string StrmConvert( F from )
{
return StrmConvert<std::string>( from );
}

typedef std::map<std::string, std::string>::iterator MIt;

class CTable
{

public:

CTable()
{
Fields_["Name"];
Fields_["Age"];
Fields_["Strength"];
Fields_["Alive"];
}

class Proxy
{
public:
Proxy(CTable& mc, std::string const& key): mc_(mc), Key_(key) {}

void operator=(int Value) { Field( Key_, StrmConvert( Value ) ); }
void operator=(unsigned int Value) { Field( Key_, StrmConvert(
Value ) ); }
void operator=(float Value) { Field( Key_, StrmConvert( Value ) ); }
void operator=(bool Value) { Field( Key_, Value ? "TRUE" :
"FALSE" ); }
void operator=(const std::string &Value) { Field( Key_, "\"" + Value
+ "\"" ); }
void operator=(const char* Value) { Field( Key_, "\"" +
std::string(Value) + "\"" ); }

private:
void Field( const std::string& Key, const std::string Value )
{
MIt it_ = mc_.Fields_.find(Key_);
if ( it_ != mc_.Fields_.end() )
(*it_).second = Value;
}

CTable& mc_;
std::string Key_;
};

Proxy operator[]( const std::string& Key )
{
return Proxy(*this, Key);
}

void OutputMap()
{
for ( MIt it = Fields_.begin(); it != Fields_.end(); ++it )
std::cout << (*it).first << ":" << (*it).second << std::endl;
}

private:
std::map<std::string, std::stringFields_;

};

class CPlayer
{
public:
CPlayer(): Name_("Serpardum"), Age_(42), Strength_(13.5f), Alive_(true)
{}
std::string Name() { return Name_; }
unsigned int Age() { return Age_; }
float Strength() { return Strength_; }
bool Alive() { return Alive_; }
private:
std::string Name_;
int Age_;
float Strength_;
bool Alive_;
};

int main()
{
CPlayer Player;
CTable PlayerTable;

PlayerTable["Name"] = Player.Name();
PlayerTable["Age"] = Player.Age();
PlayerTable["Strength"] = Player.Strength();
PlayerTable["Alive"] = Player.Alive();
PlayerTable["Bogus"] = "blah blah";

PlayerTable.OutputMap();

std::string wait;
std::cin >wait;
}
Jul 12 '06 #9

Jim Langston wrote:
template<typename T, typename F T StrmConvert( F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >to;
return to;
}

template<typename Fstd::string StrmConvert( F from )
{
return StrmConvert<std::string>( from );
}
This looks a bit flawed. When F is std::string won't it recurse
indefinitely? Also if the string has any whitespace in it, you'll find
it scans only to the first whitespace.

I would do this:

template < typename T, typename F >
bool StrmConvert( T& to, const F& from )
{
std::stringstream ss;
ss << from;
return ( ss >to );
}

which also returns whether the conversion worked.

I would then do partial specialisation.

(Can one specialise for the case where T and F are the same?: i.e
below)

template < typename T bool StrmConvert<T, T >( T & to, const F& from
)
{
to = from;
return true;
}

template < typename T bool StrmConvert< T, std::string >
template < typename T bool StrmConvert< std::string T >

then in case it doesn't know which one to pick:

template < bool StrmConvert< std::string, std::string >

(fill them in).

Jul 17 '06 #10

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

Similar topics

6
by: Kamilche | last post by:
I have a routine that I really need, but it slows down processing significantly. Can you spot any ineffeciencies in the code? This code makes a critical function of mine run about 7x slower than...
9
by: Jenta | last post by:
A World Beyond Capitalism 2005, An Annual International Multiracial Alliance Building Peace Conference Is Accepting Proposals... ...and Online Registration is now available if you plan to table...
2
by: Bryan Olson | last post by:
The current Python standard library provides two cryptographic hash functions: MD5 and SHA-1 . The authors of MD5 originally stated: It is conjectured that it is computationally infeasible to...
5
by: Kaush | last post by:
how can i make functions which behaves like printf. i mean the function should be capable of accepting variable number of arguments and of varaible types. thanx kaush
20
by: Tim Mulholland | last post by:
This thread is intended to be more of a discussion thread - because i value the opinions of the posters in this newsgroup, and especially the MVPs like Nicholas Paladino and Jon Skeet (thanks to...
52
by: mavic | last post by:
hi to everybody,i need help for my project....how to make a program that accept any integer and convert it binary,octal and hexadecimal.pls help me...thanks
7
by: Steven Bethard | last post by:
I've updated PEP 359 with a bunch of the recent suggestions. The patch is available at: http://bugs.python.org/1472459 and I've pasted the full text below. I've tried to be more explicit about...
4
by: Chris F Clark | last post by:
Please excuse the length of this post, I am unfortunately long-winded, and don't know how to make my postings more brief. I have a C++ class library (and application generator, called Yacc++(r)...
19
by: zzw8206262001 | last post by:
Hi,I find a way to make javescript more like c++ or pyhon There is the sample code: function Father(self) //every contructor may have "self" argument { self=self?self:this; ...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.