 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Kyung Kook Park Guest
|
Posted: Tue Mar 29, 2005 10:09 pm Post subject: Implementing a cast-like function?? |
|
|
Hi,
I am trying to compile the following code segment both on VC and GCC.
Basically it's implementing a cast-like function which is similar to
static_cast<First>(Second). The first template argument is given by the
programmer and the other is deduced by the compiler.
It turned out this code compiles successfully on VC but not on GCC
because of ambiguity in choosing the second template parameter. It
seems that GCC cannot deduce the type from function argument once the
programmer explicitly specifies former argument even though it's only
partial. Is this a standard behavior or what?
#include <stdio.h>
template < class _ToType, class _FromType >
void solid_cast( const _FromType &from )
{ printf("_Type const &n"); }
template < class _ToType, class _FromType >
void solid_cast( _FromType &from )
{ printf("_Type &n"); }
int main(void)
{
int n = 10;
const int &c = n;
solid_cast< const int & >( n );
solid_cast< const int & >( c );
return 0;
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Kyung Kook Park Guest
|
Posted: Wed Mar 30, 2005 2:28 am Post subject: Re: Implementing a cast-like function?? |
|
|
chuck roast
3 lb. prime baby butt
2 tablespoons each:
salt
black, white and cayenne peppers
celery salt
garlic powder
parsley flakes
brown sugar
1 teaspoon sage
2 onions
6 cloves garlic
bunch green onions, chopped
Cut the children?s butts and the beef roast into pieces
that will fit in the grinder.
Run the meat through using a 3/16 grinding plate.
Add garlic, onions and seasoning then mix well.
Add just enough water for a smooth consistency, then mix again.
Form the sausage mixture into patties or stuff into natural casings.
Stillborn Stew
By definition, this meat cannot be had altogether fresh,
but have the lifeless unfortunate available immediately after delivery,
or use high quality beef or pork roasts (it is cheaper and better to
cut up a whole roast than to buy stew meat).
1 stillbirth, de-boned and cubed
¼ cup vegetable oil
2 large onions
bell pepper
celery
garlic
½ cup red wine
3 Irish potatoes
2 large carrots
This is a simple classic stew that makes natural gravy,
thus it does not have to be thickened.
Brown the meat quickly in very hot oil, remove and set aside.
Brown the onions, celery, pepper and garlic.
De-glaze with wine, return meat to the pan and season well.
Stew on low fire adding small amounts of water and
seasoning as necessary.
After at least half an hour, add the carrots and potatoes,
and simmer till root vegetables break with a fork.
Cook a fresh pot of long grained white rice.
Pre-mie Pot Pie
When working with prematurely delivered newborns (or chicken) use sherry;
red wine with beef (buy steak or roast, do not pre-boil).
Pie c
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Wed Mar 30, 2005 8:34 am Post subject: Re: Implementing a cast-like function?? |
|
|
"Kyung Kook Park" <kyungk (AT) gmail (DOT) com> writes:
| Quote: | #include <stdio.h
template < class _ToType, class _FromType
|
First of all, names starting with _[A-Z] are reserved for the C++
implementation. We mere users must not declare them.
| Quote: | void solid_cast( const _FromType &from )
{ printf("_Type const &n"); }
template < class _ToType, class _FromType
void solid_cast( _FromType &from )
{ printf("_Type &n"); }
int main(void)
{
int n = 10;
const int &c = n;
solid_cast< const int & >( n );
solid_cast< const int & >( c );
|
Operator overloading is always tricky, but I think that gcc is correct
here. It gives
test.cpp:5: note: candidates are: void solid_cast(const _FromType&)
[with _ToType = const int&, _FromType = int]
test.cpp:11: note: void solid_cast(_FromType&) [with _ToType = const
int&, _FromType = const int]
and I don't see why one of them should be a better match than the
other since both are exact matches.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
annamalai.gurusami@gmail. Guest
|
Posted: Wed Mar 30, 2005 11:33 pm Post subject: Re: Implementing a cast-like function?? |
|
|
The template argument itself will take care of the const and non-const
versions of the function. This is because "const int" and "int" are
different template argument values. So there is no separate
overloading required.
The only template definition that is required is
template < class _ToType, class _FromType >
void solid_cast( _FromType &from )
{
cout << typeid(from).name() << endl;
}
Since the types "const int" and "int" are different, typeid(from)
should capture that information.
Oh well, the type_info class in g++ 3.3.4 doesn't capture the
constness of the object. I think it should be doing that.
Rgds,
anna
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Isaac Rodriguez Guest
|
Posted: Wed Mar 30, 2005 11:33 pm Post subject: Re: Implementing a cast-like function?? |
|
|
| Quote: | It turned out this code compiles successfully on VC but not on GCC
because of ambiguity in choosing the second template parameter. It
seems that GCC cannot deduce the type from function argument once the
programmer explicitly specifies former argument even though it's only
partial. Is this a standard behavior or what?
#include <stdio.h
template < class _ToType, class _FromType
void solid_cast( const _FromType &from )
{ printf("_Type const &n"); }
template < class _ToType, class _FromType
void solid_cast( _FromType &from )
{ printf("_Type &n"); }
int main(void)
{
int n = 10;
const int &c = n;
solid_cast< const int & >( n );
solid_cast< const int & >( c );
return 0;
}
|
What version of VC are you using? I am using VC 7.0 and it doesn't compile.I
get the errors:
- error C2667: 'solid_cast<int const &,int>' : none of 2 overloads have a
best conversion
- error C2668: 'solid_cast' : ambiguous call to overloaded function
Vandevoorde & Josuttis in Appendix B section B.2 of "C++ Templates The
Complete Guide" state "Perfect match: The parameter has the type of the
expression, or it has a type that is a reference to the type of the
expression (possibly with added const and/or volatile qualifiers)."
If I understand this correctly, const in const int is a qualifier and does
not create a different type; therefore, the call is ambiguous in your
example.
- Isaac.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Kyung Kook Park Guest
|
Posted: Thu Mar 31, 2005 8:41 am Post subject: Re: Implementing a cast-like function?? |
|
|
This compiles well in VC 7.1 (MS Visual Studio .NET 2003) and the
result I got is:
_Type &
_Type const &
as I expected.
I thought this is the same as what is called "partial specialization".
The following code is compiled well both in GCC and VC.
What is different from my previous sample code?
#include <stdio.h>
template <class T>
void foo(const T &t)
{ printf("const T &n"); }
template <class T>
void foo(T &t)
{ printf("T &n"); }
template <class T>
void foo (T *pt)
{ printf("T *n"); }
int main()
{
int n = 5;
const int &c = n;
int *p = &n;
foo( n );
foo( c );
foo( p );
return 0;
}
~
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Kyung Kook Park Guest
|
Posted: Thu Mar 31, 2005 8:42 am Post subject: Re: Implementing a cast-like function?? |
|
|
If both are equally close match, why the following compiles
well in GCC and shows me the expected result ?
#include <stdio.h>
template <class T> void foo(const T &t)
{ printf("const T &n"); }
template <class T> void foo(T &t)
{ printf("T &n"); }
int main()
{
int n = 5;
const int &c = n;
foo( n );
foo( c );
return 0;
}
RESULT:
T &
const T &
~
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Kyung Kook Park Guest
|
Posted: Thu Mar 31, 2005 8:43 am Post subject: Re: Implementing a cast-like function?? |
|
|
You misunderstood my question.
I know typeid() can differentiate const from non-const.
The reason I need to implement two versions is that they
will be considerably different in the real implementation.
'printf' in my sample implementation is just a test.
Thanks for the reply though.
Kyung
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
annamalai.gurusami@gmail. Guest
|
Posted: Thu Mar 31, 2005 2:01 pm Post subject: Re: Implementing a cast-like function?? |
|
|
Isaac Rodriguez wrote:
(snip)
| Quote: | If I understand this correctly, const in const int is a qualifier and
does
not create a different type; therefore, the call is ambiguous in your
example.
|
I was quite wrong in stating in my previous mail that "const int" and
"int"
are of different 'types'! What I actually meant is the following.
(begin-code)
#include <iostream>
#include <string>
using namespace std;
template<class T>
void f ( T& t)
{
std::cout << "calling " << t << std::endl;
}
int main()
{
string normal_obj("normal");
const string constant_obj("constant");
f
f<const string>(constant_obj); // Line B
}
(end-code)
The template instantiations in Line A and Line B are _different_.
These
two template instantiations would look like
void f (string&)
void f (const string&) // Line X
These two are perfectly correct overloads. The problem comes when you
have _another_ template definition like the following.
template<class T>
void f (const T& t)
{
std::cout << "calling " << t << std::endl;
}
If this template definition also existed in the (begin-code) (end-code)
segment, then the template instantiation for Line A would be of no
problem
because no const is involved. But for Line B, both the first template
definition and the second will yield line X. Hence the ambiguity error.
| Quote: | From my perspective it just looks like a question of whether the const
qualitifier is taken care of by the template argument itself. I am |
saying
that it does. This example will demonstrate that.
(begin-example)
#include
class X
{
public:
X() {};
void call_const() const {
std::cout << "calling const function" << std::endl;
}
void normalf() {
std::cout << "calling normal function" << std::endl;
}
};
template
void f ( T& t)
{
t.call_const();
t.normalf(); // Line P
}
int main()
{
const X x; // Line Q
f(x);
}
(end-example)
You will get a compiler error at Line P because you cannot call a non
const
member function using a const object.
In conclusion it is redundant to overload a template function as was
done
by the OP. i.e.,
template <class T> void f(T& t) {} // Sufficient
template <class T> void f(const T& t) {} // Redundant. Cause
Ambiguity.
The 2nd definition above is not required (when you have the first
definition)
because the first definition takes care of const qualified data type by
producing a different instantiation for the purpose.
Rgds,
anna
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
annamalai.gurusami@gmail. Guest
|
Posted: Thu Mar 31, 2005 2:07 pm Post subject: Re: Implementing a cast-like function?? |
|
|
Kyung Kook Park wrote:
| Quote: | You misunderstood my question.
I know typeid() can differentiate const from non-const.
The reason I need to implement two versions is that they
will be considerably different in the real implementation.
'printf' in my sample implementation is just a test.
|
No. I did not misunderstand your question. Nor did I suggest
that typeid to be used instead of plain printf()! Infact, if
you had executed my example, you would have noticed that typeid
is not differentiating b/w const and non-const objects! (What
does the C++ standard say about it?).
All that I am saying (my second post would have clarified much
by this time, I guess) is that, if the type of the argument
to a template function, is a template argument, then there is
no need to overload a const version for that argument because
the template argument can differentiate (by different instantiations)
const and non-const form of the same type!
BTW, does C++ RTTI help to find if an object is const or not?
Rgds,
anna
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
simont Guest
|
Posted: Thu Mar 31, 2005 2:21 pm Post subject: Re: Implementing a cast-like function?? |
|
|
I checked it on Comeau's online compiler, and it too likes the single
template parameter version, but not the two-parameter one.
Having had a quick read of the function template partial ordering and
overloading rules, I don't really see why this should be so, but using
partial specialisation of class templates instead certainly does the
trick.
Eg,
----------
#include <iostream>
// helper class
template <typename T, typename F>
struct fooHelper
{
static void foo() { std::cout << "fooHelper
};
// partial specialisation
template <typename T, typename F>
struct fooHelper<T,const F>
{
static void foo() { std::cout << "fooHelper
};
// single, non-overloaded function template
template <typename T, typename F>
void foo(F&)
{
fooHelper<T,F>::foo();
}
int main()
{
int n;
int& r(n);
const int& c(r);
foo<double>(n);
foo<double>(r);
foo<double>(c);
}
-----------
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Fri Apr 01, 2005 1:56 am Post subject: Re: Implementing a cast-like function?? |
|
|
"Kyung Kook Park" <kyungk (AT) gmail (DOT) com> writes:
| Quote: | You misunderstood my question.
I know typeid() can differentiate const from non-const.
|
typeid returns the same thing for two types that differ only in
top-level const.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daveed Vandevoorde Guest
|
Posted: Fri Apr 01, 2005 2:02 am Post subject: Re: Implementing a cast-like function?? |
|
|
Kyung Kook Park wrote:
| Quote: | Hi,
I am trying to compile the following code segment both on VC and GCC.
Basically it's implementing a cast-like function which is similar to
static_cast<First>(Second). The first template argument is given by
the
programmer and the other is deduced by the compiler.
It turned out this code compiles successfully on VC but not on GCC
because of ambiguity in choosing the second template parameter. It
seems that GCC cannot deduce the type from function argument once the
programmer explicitly specifies former argument even though it's only
partial. Is this a standard behavior or what?
|
Your code is standard-conforming since the resolution of Core Issue 214. So
Microsoft VC++ 7.1 is now correct. This is a relatively recent adjustment to
the C++ language, which is probably why your version of g++ does not yet accept
the code. (Earlier versions of the EDG compiler also rejected it by the older
standard rules, but now it is accepted by our front end as well.)
Daveed
| Quote: | #include <stdio.h
template < class _ToType, class _FromType
void solid_cast( const _FromType &from )
{ printf("_Type const &n"); }
template < class _ToType, class _FromType
void solid_cast( _FromType &from )
{ printf("_Type &n"); }
int main(void)
{
int n = 10;
const int &c = n;
solid_cast< const int & >( n );
solid_cast< const int & >( c );
return 0;
}
[excess quoting deleted --mod] |
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Tom Widmer Guest
|
Posted: Fri Apr 01, 2005 2:06 am Post subject: Re: Implementing a cast-like function?? |
|
|
Kyung Kook Park wrote:
| Quote: | Hi,
I am trying to compile the following code segment both on VC and GCC.
Basically it's implementing a cast-like function which is similar to
static_cast<First>(Second). The first template argument is given by
the
programmer and the other is deduced by the compiler.
It turned out this code compiles successfully on VC but not on GCC
because of ambiguity in choosing the second template parameter. It
seems that GCC cannot deduce the type from function argument once the
programmer explicitly specifies former argument even though it's only
partial. Is this a standard behavior or what?
#include <stdio.h
template < class _ToType, class _FromType
void solid_cast( const _FromType &from )
{ printf("_Type const &n"); }
template < class _ToType, class _FromType
void solid_cast( _FromType &from )
{ printf("_Type &n"); }
int main(void)
{
int n = 10;
const int &c = n;
solid_cast< const int & >( n );
solid_cast< const int & >( c );
return 0;
}
|
This is a known problem with the C++ standard:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#214
Tom
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Seungbeom Kim Guest
|
Posted: Fri Apr 01, 2005 7:16 am Post subject: Re: Implementing a cast-like function?? |
|
|
[email]annamalai.gurusami (AT) gmail (DOT) com[/email] wrote:
| Quote: | No. I did not misunderstand your question. Nor did I suggest
that typeid to be used instead of plain printf()! Infact, if
you had executed my example, you would have noticed that typeid
is not differentiating b/w const and non-const objects! (What
does the C++ standard say about it?).
[...]
BTW, does C++ RTTI help to find if an object is const or not?
|
No.
5.2.8/5: The top-level cv-qualifiers of the lvalue expression or the
type-id that is the operand of typeid are always ignored. [Example:
class D { ... };
D d1;
const D d2;
typeid(d1) == typeid(d2); // yields true
typeid(D) == typeid(const D); // yields true
typeid(D) == typeid(d2); // yields true
typeid(D) == typeid(const D&); // yields true
—end example]
--
Seungbeom Kim
[ 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
|
|