473,385 Members | 1,342 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.

template functions and "return type overloading"

I have the following code segment - which compiles fine. I'm just
worried I may get run time probs - because it looks like the functions
are being overloaded by the return types?. Is this Ok: ?

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

template <class T1, class T2>
std::string getValue( T1 col, T2 row ) ;

template <class T1, class T2>
Table getValue( T1 col, T2 row ) ;

.... etc.

Jul 23 '05 #1
9 2709
Ann Huxtable wrote:
I have the following code segment - which compiles fine. I'm just
It shouldn't. You cannot overload functions on their return value only:

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

int main()
{
int a = getValue(1, 2);
}

"ComeauTest.c", line 9: error: more than one instance of overloaded
function
"getValue" matches the argument list, the choices that match
are:
function template "getValue(T1, T2)"
function template "getValue(T1, T2)"
The argument types that you used are: (int, int)
int a = getValue(1, 2);

It will compile until you try to call one of the overloads.
worried I may get run time probs - because it looks like the functions
are being overloaded by the return types?. Is this Ok: ?
No.
template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

template <class T1, class T2>
std::string getValue( T1 col, T2 row ) ;

template <class T1, class T2>
Table getValue( T1 col, T2 row ) ;

... etc.


What are you trying to achieve?
Jonathan

Jul 23 '05 #2
> I have the following code segment - which compiles fine. I'm just
worried I may get run time probs - because it looks like the functions
are being overloaded by the return types?. Is this Ok: ?

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

template <class T1, class T2>
std::string getValue( T1 col, T2 row ) ;

template <class T1, class T2>
Table getValue( T1 col, T2 row ) ;

... etc.


Hmm, I must say I am surprised that these declarations compile. But bear in
mind there are all but template declaration nevertheless. The compiler won't
issue any error until it has to instantiate the template, such as an
explicit template instantiation or a call to the function template:

template int getValue(int, int); // error
int a = getValue(1,2); // error

Regards,
Ben
Jul 23 '05 #3


Jonathan Mcdougall wrote:
Ann Huxtable wrote:
I have the following code segment - which compiles fine. I'm just

It shouldn't. You cannot overload functions on their return value only:

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

int main()
{
int a = getValue(1, 2);
}

"ComeauTest.c", line 9: error: more than one instance of overloaded
function
"getValue" matches the argument list, the choices that match
are:
function template "getValue(T1, T2)"
function template "getValue(T1, T2)"
The argument types that you used are: (int, int)
int a = getValue(1, 2);

It will compile until you try to call one of the overloads.

worried I may get run time probs - because it looks like the functions
are being overloaded by the return types?. Is this Ok: ?

No.

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

template <class T1, class T2>
std::string getValue( T1 col, T2 row ) ;

template <class T1, class T2>
Table getValue( T1 col, T2 row ) ;

... etc.

What are you trying to achieve?
Jonathan


I'm writing a "Table" class which mimics a table returned in an SQL
query. The only difference is that in my table, I want to be able to
nest tables within tables - so some columns will contain other table.

To answer your question regarding whT i'm trying to achieve, the
templated functions above are retriving the values stored in a cell. The
cell is currently implemented as a union (although I may change to the
Boost variant type at a later stage). The cell can store one of the
following types:

char*
int,
double
void * //To allow nesting
Cells are referenced by (row,col) where each of the parameters could
either be a string (name) or int (index). This permutated with the large
number of possible return variables will result in 4*4 = 16 functions
just to get a value, and then another 16 to set a value - and this is
not easily extensible if I need to store other variable types. Hence my
post.

If you have any ideas as to how to solve this problem, I'd be willing to
hear them. Tks

Jul 23 '05 #4
Ann Huxtable wrote:
Jonathan Mcdougall wrote:
Ann Huxtable wrote:
I have the following code segment - which compiles fine. I'm just


It shouldn't. You cannot overload functions on their return value only:
What are you trying to achieve?


I'm writing a "Table" class which mimics a table returned in an SQL
query. The only difference is that in my table, I want to be able to
nest tables within tables - so some columns will contain other table.

To answer your question regarding whT i'm trying to achieve, the
templated functions above are retriving the values stored in a cell. The
cell is currently implemented as a union (although I may change to the
Boost variant type at a later stage). The cell can store one of the
following types:

char*
int,
double
void * //To allow nesting
Cells are referenced by (row,col) where each of the parameters could
either be a string (name) or int (index). This permutated with the large
number of possible return variables will result in 4*4 = 16 functions
just to get a value, and then another 16 to set a value - and this is
not easily extensible if I need to store other variable types. Hence my
post.

If you have any ideas as to how to solve this problem, I'd be willing to
hear them. Tks


Include the return in the template list:

#include <string>
#include <sstream>

template <class Ret, class T1, class T2>
Ret getValue(T1 col, T2 row)
{
std::string value = get_value_from_db_as_string(col, row);

std::istringstream iss(value);
Ret r = Ret();

iss >> r;

return r;
}

int main()
{
int a = getValue<int>(10, 10);
double b = getValue<double>(11, 11);
Image c(getValue<Image>(12, 12)); // provided Image overloaded the
operator>>
}

If you cannot get the value as a string from the database, you'll have
to find another way. Come back if you didn't find any.
Jonathan

Jul 23 '05 #5


Jonathan Mcdougall wrote:
Ann Huxtable wrote:
Jonathan Mcdougall wrote:

Ann Huxtable wrote:
I have the following code segment - which compiles fine. I'm just

It shouldn't. You cannot overload functions on their return value only:
What are you trying to achieve?


I'm writing a "Table" class which mimics a table returned in an SQL
query. The only difference is that in my table, I want to be able to
nest tables within tables - so some columns will contain other table.

To answer your question regarding whT i'm trying to achieve, the
templated functions above are retriving the values stored in a cell. The
cell is currently implemented as a union (although I may change to the
Boost variant type at a later stage). The cell can store one of the
following types:

char*
int,
double
void * //To allow nesting
Cells are referenced by (row,col) where each of the parameters could
either be a string (name) or int (index). This permutated with the large
number of possible return variables will result in 4*4 = 16 functions
just to get a value, and then another 16 to set a value - and this is
not easily extensible if I need to store other variable types. Hence my
post.

If you have any ideas as to how to solve this problem, I'd be willing to
hear them. Tks

Include the return in the template list:

#include <string>
#include <sstream>

template <class Ret, class T1, class T2>
Ret getValue(T1 col, T2 row)
{
std::string value = get_value_from_db_as_string(col, row);

std::istringstream iss(value);
Ret r = Ret();

iss >> r;

return r;
}

int main()
{
int a = getValue<int>(10, 10);
double b = getValue<double>(11, 11);
Image c(getValue<Image>(12, 12)); // provided Image overloaded the
operator>>
}

If you cannot get the value as a string from the database, you'll have
to find another way. Come back if you didn't find any.
Jonathan


The database example I gave was just a conceptul illustration. I will
not necesarily be loading data from a db. I think the simplest
implementation would be to create templated functions (for each of the
data types supported - i.e. getString(), getLong(), getNestedTable() etc.

Thanks for your help nonetheless ..

Jul 23 '05 #6

"Ann Huxtable" <an*********@research.de.edu> wrote in message
news:db**********@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...


Jonathan Mcdougall wrote:
Ann Huxtable wrote:
I have the following code segment - which compiles fine. I'm just

It shouldn't. You cannot overload functions on their return value only:

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

int main()
{
int a = getValue(1, 2);
}

"ComeauTest.c", line 9: error: more than one instance of overloaded
function
"getValue" matches the argument list, the choices that match
are:
function template "getValue(T1, T2)"
function template "getValue(T1, T2)"
The argument types that you used are: (int, int)
int a = getValue(1, 2);

It will compile until you try to call one of the overloads.

worried I may get run time probs - because it looks like the functions
are being overloaded by the return types?. Is this Ok: ?

No.

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

template <class T1, class T2>
std::string getValue( T1 col, T2 row ) ;

template <class T1, class T2>
Table getValue( T1 col, T2 row ) ;

... etc.

What are you trying to achieve?
Jonathan


I'm writing a "Table" class which mimics a table returned in an SQL
query. The only difference is that in my table, I want to be able to
nest tables within tables - so some columns will contain other table.

To answer your question regarding whT i'm trying to achieve, the
templated functions above are retriving the values stored in a cell. The
cell is currently implemented as a union (although I may change to the
Boost variant type at a later stage). The cell can store one of the
following types:

char*
int,
double
void * //To allow nesting
Cells are referenced by (row,col) where each of the parameters could
either be a string (name) or int (index). This permutated with the large
number of possible return variables will result in 4*4 = 16 functions
just to get a value, and then another 16 to set a value - and this is
not easily extensible if I need to store other variable types. Hence my
post.

If you have any ideas as to how to solve this problem, I'd be willing to
hear them. Tks


Now, what you described is indeed three problems: input types, output types,
and extensibility. Let's take them apart:

You are looking for int-int, int-string, string-int, string-string pairs as
input type and are looking for extensibility, if I correctly understand your
post. The ideal way is to use the C++ type system to help you. What's in my
mind is a single concept for locating a cell, say, cell_entry:

class cell_entry_base
{
protected:
cell_entry_base();
// whatever you need to know to locate a cell
};

// map to col-row pair types
template <typename ColT, typename RowT>
class cell_entry;

// specialize for <int, int>
template <> class cell_entry<int, int>: public cell_entry_base
{
//...
};

// also specialize for <int, string>, <string, int> and <string, string>
//...

// also specialize for other types you wish, extending made easy...

Now the output type. You need to map a set of C++ type to the internal types
supported by the database, if I am still on the track. So I came up with
traits:

template <typename T>
class entry_type_trait;

template <> class entry_type_trait<char*>
{
public:
static char* get_value(cell_entry_base&) throw (bad_type)
{
// your database access code here,
// throw bad_type if type not matched
}

//... more ops up to you
};

// also specialize for <int> <double> and <void*>
// ...

Note that you only have to add a new specialization to extend the type
mapping. And finally the function getValue can be trivially implemented:

template <typename ReturnT, typename ColT, typename RowT>
ReturnT getValue(ColT col, RowT row) throw (bad_type)
{
cell_entry<ColT, RowT> entry(col, row); // enforce input types
return entry_type_trait<ReturnT>::get_value(entry); // output
types
}

Regards,
Ben
Jul 23 '05 #7


benben wrote:
"Ann Huxtable" <an*********@research.de.edu> wrote in message
news:db**********@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...

Jonathan Mcdougall wrote:

Ann Huxtable wrote:
I have the following code segment - which compiles fine. I'm just
It shouldn't. You cannot overload functions on their return value only:

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

int main()
{
int a = getValue(1, 2);
}

"ComeauTest.c", line 9: error: more than one instance of overloaded
function
"getValue" matches the argument list, the choices that match
are:
function template "getValue(T1, T2)"
function template "getValue(T1, T2)"
The argument types that you used are: (int, int)
int a = getValue(1, 2);

It will compile until you try to call one of the overloads.

worried I may get run time probs - because it looks like the functions
are being overloaded by the return types?. Is this Ok: ?
No.

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

template <class T1, class T2>
std::string getValue( T1 col, T2 row ) ;

template <class T1, class T2>
Table getValue( T1 col, T2 row ) ;

... etc.
What are you trying to achieve?
Jonathan


I'm writing a "Table" class which mimics a table returned in an SQL
query. The only difference is that in my table, I want to be able to
nest tables within tables - so some columns will contain other table.

To answer your question regarding whT i'm trying to achieve, the
templated functions above are retriving the values stored in a cell. The
cell is currently implemented as a union (although I may change to the
Boost variant type at a later stage). The cell can store one of the
following types:

char*
int,
double
void * //To allow nesting
Cells are referenced by (row,col) where each of the parameters could
either be a string (name) or int (index). This permutated with the large
number of possible return variables will result in 4*4 = 16 functions
just to get a value, and then another 16 to set a value - and this is
not easily extensible if I need to store other variable types. Hence my
post.

If you have any ideas as to how to solve this problem, I'd be willing to
hear them. Tks

Now, what you described is indeed three problems: input types, output types,
and extensibility. Let's take them apart:

You are looking for int-int, int-string, string-int, string-string pairs as
input type and are looking for extensibility, if I correctly understand your
post. The ideal way is to use the C++ type system to help you. What's in my
mind is a single concept for locating a cell, say, cell_entry:

class cell_entry_base
{
protected:
cell_entry_base();
// whatever you need to know to locate a cell
};

// map to col-row pair types
template <typename ColT, typename RowT>
class cell_entry;

// specialize for <int, int>
template <> class cell_entry<int, int>: public cell_entry_base
{
//...
};

// also specialize for <int, string>, <string, int> and <string, string>
//...

// also specialize for other types you wish, extending made easy...

Now the output type. You need to map a set of C++ type to the internal types
supported by the database, if I am still on the track. So I came up with
traits:

template <typename T>
class entry_type_trait;

template <> class entry_type_trait<char*>
{
public:
static char* get_value(cell_entry_base&) throw (bad_type)
{
// your database access code here,
// throw bad_type if type not matched
}

//... more ops up to you
};

// also specialize for <int> <double> and <void*>
// ...

Note that you only have to add a new specialization to extend the type
mapping. And finally the function getValue can be trivially implemented:

template <typename ReturnT, typename ColT, typename RowT>
ReturnT getValue(ColT col, RowT row) throw (bad_type)
{
cell_entry<ColT, RowT> entry(col, row); // enforce input types
return entry_type_trait<ReturnT>::get_value(entry); // output
types
}

Regards,
Ben


Ok, this looks interesting, I'm re-reading your post to make sure I
understand it completely (BTW, I believe you are on the right track -
i.e. you *did understand the problem posed). If I encounter any probs
with your solution, I'll be right back. tks

Jul 23 '05 #8


Ann Huxtable wrote:


benben wrote:
"Ann Huxtable" <an*********@research.de.edu> wrote in message
news:db**********@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...

Jonathan Mcdougall wrote:
Ann Huxtable wrote:
> I have the following code segment - which compiles fine. I'm just

It shouldn't. You cannot overload functions on their return value only:

template <class T1, class T2>
int getValue( T1 col, T2 row ) ;

template <class T1, class T2>
double getValue( T1 col, T2 row ) ;

int main()
{
int a = getValue(1, 2);
}

"ComeauTest.c", line 9: error: more than one instance of overloaded
function
"getValue" matches the argument list, the choices that match
are:
function template "getValue(T1, T2)"
function template "getValue(T1, T2)"
The argument types that you used are: (int, int)
int a = getValue(1, 2);

It will compile until you try to call one of the overloads.

> worried I may get run time probs - because it looks like the functions
> are being overloaded by the return types?. Is this Ok: ?

No.

> template <class T1, class T2>
> int getValue( T1 col, T2 row ) ;
>
> template <class T1, class T2>
> double getValue( T1 col, T2 row ) ;
>
> template <class T1, class T2>
> std::string getValue( T1 col, T2 row ) ;
>
> template <class T1, class T2>
> Table getValue( T1 col, T2 row ) ;
>
> ... etc.

What are you trying to achieve?
Jonathan
I'm writing a "Table" class which mimics a table returned in an SQL
query. The only difference is that in my table, I want to be able to
nest tables within tables - so some columns will contain other table.

To answer your question regarding whT i'm trying to achieve, the
templated functions above are retriving the values stored in a cell. The
cell is currently implemented as a union (although I may change to the
Boost variant type at a later stage). The cell can store one of the
following types:

char*
int,
double
void * //To allow nesting
Cells are referenced by (row,col) where each of the parameters could
either be a string (name) or int (index). This permutated with the large
number of possible return variables will result in 4*4 = 16 functions
just to get a value, and then another 16 to set a value - and this is
not easily extensible if I need to store other variable types. Hence my
post.

If you have any ideas as to how to solve this problem, I'd be willing to
hear them. Tks

Now, what you described is indeed three problems: input types, output
types,
and extensibility. Let's take them apart:

You are looking for int-int, int-string, string-int, string-string
pairs as
input type and are looking for extensibility, if I correctly
understand your
post. The ideal way is to use the C++ type system to help you. What's
in my
mind is a single concept for locating a cell, say, cell_entry:

class cell_entry_base
{
protected:
cell_entry_base();
// whatever you need to know to locate a cell
};

// map to col-row pair types
template <typename ColT, typename RowT>
class cell_entry;

// specialize for <int, int>
template <> class cell_entry<int, int>: public cell_entry_base
{
//...
};

// also specialize for <int, string>, <string, int> and <string,
string>
//...

// also specialize for other types you wish, extending made easy...

Now the output type. You need to map a set of C++ type to the internal
types
supported by the database, if I am still on the track. So I came up with
traits:

template <typename T>
class entry_type_trait;

template <> class entry_type_trait<char*>
{
public:
static char* get_value(cell_entry_base&) throw (bad_type)
{
// your database access code here,
// throw bad_type if type not matched
}

//... more ops up to you
};

// also specialize for <int> <double> and <void*>
// ...

Note that you only have to add a new specialization to extend the type
mapping. And finally the function getValue can be trivially implemented:

template <typename ReturnT, typename ColT, typename RowT>
ReturnT getValue(ColT col, RowT row) throw (bad_type)
{
cell_entry<ColT, RowT> entry(col, row); // enforce input
types
return entry_type_trait<ReturnT>::get_value(entry); // output
types
}

Regards,
Ben


Ok, this looks interesting, I'm re-reading your post to make sure I
understand it completely (BTW, I believe you are on the right track -
i.e. you *did understand the problem posed). If I encounter any probs
with your solution, I'll be right back. tks


This is quite an elegant approach (albeit a bit confusing - to me
atleast). You may hev been also led slight astray by the special case of
loading data from a database into this memory table - however, the
proposed implimentation is still apropriate nonetheless.

Would you care to elaborate exactly what the base class cell_entry_base
does (you noted: // whatever you need to know to locate a cell). I'd
also be grateful if you add a little more flesh (or at least comments to
the template specializations for class cell_entry). It is likely that I
may have to come back to you several times during my implementation - I
hope you don't mind :-) (please indicate if you are too busy to assist
- though, in which case I'll keep it simple and use my less elegant
method - but I really like this more compact approach...)

Jul 23 '05 #9
> This is quite an elegant approach (albeit a bit confusing - to me
atleast). You may hev been also led slight astray by the special case of
loading data from a database into this memory table - however, the
proposed implimentation is still apropriate nonetheless.

Would you care to elaborate exactly what the base class cell_entry_base
does (you noted: // whatever you need to know to locate a cell). I'd
also be grateful if you add a little more flesh (or at least comments to
the template specializations for class cell_entry). It is likely that I
may have to come back to you several times during my implementation - I
hope you don't mind :-) (please indicate if you are too busy to assist
- though, in which case I'll keep it simple and use my less elegant
method - but I really like this more compact approach...)


I am glad I have been a littel helpful.

The class cell_entry_base is designed to consist any data or operation that
is necessary to locate a cell in your database. This is highly
implementation dependent--how it is implemented is directly related to the
database you are using. In situations where multi-connection, multi-table
database are concerned, you probably have to elaborate the class even a
little further.

That said, if your database can always use an int-int pair to locate a cell
directly, cell_entry_base is quite triviall:

class cell_entry_base
{
public:
int col;
int row;

// ...
};
Regards,
Ben
Jul 23 '05 #10

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

Similar topics

12
by: zealotcat | last post by:
template <class T> inline T const& max (T const& a, T const& b) { // if a < b then use b else use a return a<b?b:a; } thanks very much!!
1
by: Mat DeLong | last post by:
Can someone explain this error to me? : main.cpp:9: instantiated from `void show(const LIST::List<T>&) ' main.cpp:23: instantiated from here list.cpp:58: error: dependent-name...
32
by: Mike Machuidel | last post by:
Hi, I'm a game developer programming mostly in C and ASM for about 7 years. Today at work a colleague (a C++ programmer) yelled at me I'm a bad C programmer because I use "return(0);" instead...
10
by: LaEisem | last post by:
On-the-job, I have "inherited" a lot of old C language software. A question or two about when "casting" of null pointer constants is needed has occurred during behind-the-scenes cleanup of some...
15
by: Greenhorn | last post by:
Hi, when a function doesn't specify a return type ,value what value is returned. In the below programme, the function sample()is returning the value passed to 'k'. sample(int); main() { int...
4
by: yaru22 | last post by:
In one of the examples in the book I'm reading, it says: def __init__(self): ... ... ... return It has nothing after "return". I expected it to have some number like 0 or 1.
20
by: Andreas Griesmayer | last post by:
Hi, following piece of code causes a strange behavior when compiled with GCC (Linux, Gentoo 3.3.5.20050130-r1). read() is called twice although only called once, the first time before the first...
24
by: carnold | last post by:
Hello, I'm a developer coming from C++ and Java ... I've going thru "Effective C#" (which highly recommend for people coming from other languages wanting to learn C#), and it states that "value...
9
by: Steve | last post by:
Hi; I've being going through some legacy code on an old JSP site I have been patching. I noticed that when I save the JSP down to my PC as an HTML file I get this javascript error in IE 6 ( ...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
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:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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?
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.