C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Implementing a cast-like function??
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Kyung Kook Park
Guest





PostPosted: Tue Mar 29, 2005 10:09 pm    Post subject: Implementing a cast-like function?? Reply with 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;
}


[ 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





PostPosted: Wed Mar 30, 2005 2:28 am    Post subject: Re: Implementing a cast-like function?? Reply with quote



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





PostPosted: Wed Mar 30, 2005 8:34 am    Post subject: Re: Implementing a cast-like function?? Reply with quote



"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





PostPosted: Wed Mar 30, 2005 11:33 pm    Post subject: Re: Implementing a cast-like function?? Reply with quote

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





PostPosted: Wed Mar 30, 2005 11:33 pm    Post subject: Re: Implementing a cast-like function?? Reply with quote

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





PostPosted: Thu Mar 31, 2005 8:41 am    Post subject: Re: Implementing a cast-like function?? Reply with quote

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





PostPosted: Thu Mar 31, 2005 8:42 am    Post subject: Re: Implementing a cast-like function?? Reply with quote

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





PostPosted: Thu Mar 31, 2005 8:43 am    Post subject: Re: Implementing a cast-like function?? Reply with 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.

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





PostPosted: Thu Mar 31, 2005 2:01 pm    Post subject: Re: Implementing a cast-like function?? Reply with quote

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





PostPosted: Thu Mar 31, 2005 2:07 pm    Post subject: Re: Implementing a cast-like function?? Reply with quote

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





PostPosted: Thu Mar 31, 2005 2:21 pm    Post subject: Re: Implementing a cast-like function?? Reply with quote

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





PostPosted: Fri Apr 01, 2005 1:56 am    Post subject: Re: Implementing a cast-like function?? Reply with quote

"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





PostPosted: Fri Apr 01, 2005 2:02 am    Post subject: Re: Implementing a cast-like function?? Reply with quote


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





PostPosted: Fri Apr 01, 2005 2:06 am    Post subject: Re: Implementing a cast-like function?? Reply with quote


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





PostPosted: Fri Apr 01, 2005 7:16 am    Post subject: Re: Implementing a cast-like function?? Reply with quote

[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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.