-
A question regarding cast operator
Here is the code,
Code:
class B
{
};
class A
{
public:
operator B*()
{
B* pB = new B;
return pB;
}
};
int main()
{
A a;
B* pB = (B*)a; // #1
B* pB = static_cast<B*> (a); // #2
return 0;
}
When I use cast operator defined in class A, should I use statement #1 or #2? BTW, they both compile. Thanks.
-
Re: A question regarding cast operator
I would say that in a C++ code you should never use a C-style cast and in a perfect world you shouldn't use cast as all...
A C-style cast isn't as search friendly as a c++ cast i.e whenever you change stuff they still are there silenting the compiler.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
S_M_A
I would say that in a C++ code you should never use a C-style cast and in a perfect world you shouldn't use cast as all...
A C-style cast isn't as search friendly as a c++ cast i.e whenever you change stuff they still are there silenting the compiler.
You are absolutely right. But my question is that is cast operator *() always equivalent to static_cast? Thanks.
-
Re: A question regarding cast operator
I'm pretty sure that both are required to work correctly according to the standard, but don't take my word on it. Someone more familiar with the standard, please verify. They both work for me, but that's no guarantee of the behavior with all compilers under all optimizations.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
LarryChen
When I use cast operator defined in class A, should I use statement #1 or #2? BTW, they both compile. Thanks.
I've never found a reason to use the conversion operator so I may be wrong here but if you define a conversion operator why do you need to cast at all? Why don't you simply do,
B* pB = a; // #3
All of #1, #2 and #3 work but if you remove the conversion operator from A none of them will. That means they're all functionally equivalent in this case. They all simply invoke the conversion operator.
Generally they're not equivalent though. When you cast explicitly you're recommended to use one of the "new" more targeted casts. In this case it would be static_cast.
-
Re: A question regarding cast operator
They aren't equivalent as far as I know.
Code:
B * pB = static_cast<B*>(a)
means I want to treat it as B*, is that okay compiler?
means, screw what the compiler thinks, I'm casting it anyway.
In fact, because a is not a pointer, I'm pretty sure if there wasn't an explicit cast operator, it would fail compilation (or at least warn.)
Just FYI LarryChen, your code in the initial post leaks memory.
-
Re: A question regarding cast operator
-
Re: A question regarding cast operator
Quote:
Originally Posted by
ninja9578
They aren't equivalent as far as I know.
They aren't, but:
Quote:
Originally Posted by
ninja9578
Code:
B * pB = static_cast<B*>(a)
means I want to treat it as B*, is that okay compiler?
means, screw what the compiler thinks, I'm casting it anyway.
What do you mean?
I thought c-style casts call C++-style casts in some order?
@OP: BTW, although casts should generally be avoided, occasionally you do need to use them (for example, even if you can design your way out of it, the resulting code can end up being rather convoluted and even less performant, rendering the cast-based version both more elegant and more efficient).
Also, here's a different view advocating against C++-style casts. IM(H)O, the guy has a point, and if you're gonna use C++-style casts, it should be for very specific reasons on very specific places.
Of course, C++-style casts are considered a good C++ programming practice, so many people here will not agree.
In the end, it's really up to you to learn more about both and form your own opinion.
-
Re: A question regarding cast operator
He has some points for sure but for me the strongest argument for not using C-style casts is that they are more or less impossible to find without reading every single line of code.
C++-style casts is easy to find, a search for _cast reveals them all to be thoroughly reviewed.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
TheGreatCthulhu
I thought c-style casts call C++-style casts in some order?
yes, but given that:
1- how those c-casts are interpreted in terms of c++-casts depends on further rules usually ignored by c-cast users ( that is, if they knew them they probably knew how to use c++-casts and hence avoid c-casts in the first place )
2- those rules are such as to give the more "relaxed" behavior
hence it's fair to say that a c-cast "means, screw what the compiler thinks, I'm casting it anyway."
Quote:
Originally Posted by
TheGreatCthulhu
so many people here will not agree.
I definitely disagree indeed ! :)
Quote:
Originally Posted by
TheGreatCthulhu
IM(H)O, the guy has a point
Quote:
Originally Posted by S_M_A
He has some points for sure
just for the sake of discussion, which are them ?
-
Re: A question regarding cast operator
@S_M_A:
OK, that's true.
If there's a need to search for C-style casts, one might use VS regular expressions in the find dialog, something along these lines: "=:b*\(.*\)".
But, that might not find all the occurrences, and the fact that you need to come up with a cryptic regular expression makes the method error prone.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
superbonzo
just for the sake of discussion, which are them ?
You didn't find it reasonable an assumption that they could be stated in the article? :D
OK. According to Mr Kalev there:
- C-style casts may perform more than one conversion at once - so what?
- C-style casts make the code clearer.
- Specialized cast operators are an example of over-engineering. [I'd like to add that's good if you have more tools in your toolbox, but that doesn't mean you should always use them.]
- According to him static_cast isn't good for anything, and even Strosutrup discourages its use [although I'd say that that statement is possibly pulled out of context].
- The code can compile without casting [as nuzzle pointed out].
Quote:
Originally Posted by Danny Kalev
Derived *p= pbase;
int result= 12.56; //yes, this code compiles
void*opaque =&myobj;
- According to Kalev, C++ cast operators are dangerous [if I understood well, to novice programmers or to those who don't fully understand all the differences between various cast operators].
- C-style casts are context-sensitive.
- "ugly cast operators [don’t] dissuade them from using casts. [...] Programmers use casts not because they’re fun but because they are needed, or at least considered as needed."
- Although C-style casts are harder to find, the argument is weakened by: (1) "many conversions in a C++ program are implicit, and don’t use any cast operator", and (2) you can use both C-style casts and C++-style casts in the same program. He also tried to make a point that you need to search for different cast operators, but as S_M_A noticed, one can just search for "_cast". :D
-
Re: A question regarding cast operator
Quote:
Originally Posted by TheGreatCthulhu
The code can compile without casting [as nuzzle pointed out].
If the conversion function was declared as explicit then that would not be so.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
TheGreatCthulhu
You didn't find it reasonable an assumption that they could be stated in the article?
yes I did; mine was a rhetoric question because I didn't actually find any; moreover, I know you like bullet lists :D ...
Quote:
Originally Posted by
TheGreatCthulhu
YAccording to Mr Kalev there:
he's just combining obvious observations with unwarranted assumptions coming to debatable conclusions ...
BTW, IMHO the only situation where c++ casts are unusable is with explicit arithmetic conversions; anyway, even then I always use the functional notation in this case; yes, it's functionally equivalent for non-class types, but it's more coherent ( the same syntax is used with objects of class types; also, consider generic code ) and less abuse-prone ( you need a typedef to perform complex pointer/reference conversions in functional notation ).
-
Re: A question regarding cast operator
@laserlight:
(sorry for the slow reply, I went out in the meantime, so I'm typing this on my phone)
Yes, but his (Kalev's) point was that there
could be conversions in the code that aren't going to be found by the "_cast" search anyway.
It all boils down to personal reasons/judgement, and how well the code is designed.
Tell me: how many times will be significantly important to have control over the cast process? And I by that I mean that there's a strong reason to do so.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
superbonzo
yes I did; mine was a rhetoric question because I didn't actually find any; moreover, I know you like bullet lists :D ...
XD
About casts: OK. But I think it's fair to let the OP decide. There's the smal matter of "experience required in order to do so", in which case: do what the C++ experts say :D.
But there's always room for re-evaluation of adopted practices. Fair enough?
-
Re: A question regarding cast operator
Quote:
Originally Posted by
superbonzo
just for the sake of discussion, which are them ?
He's correct that, by a novice, they might be faulty used but as they are searchable (IMO) that's not a big issue. A faulty C++ cast should easily be detected and corrected during a peer-review. I don't know about you but the first thing I do in a review is a search for _cast without the need to invent any clever regular expression. For me finding a C-style cast is a cause for a review rejection of the code.
-
Re: A question regarding cast operator
Quote:
Originally Posted by Danny Kalev
Derived *p= pbase;
int result= 12.56; //yes, this code compiles
void*opaque =&myobj;
On what compiler would the first line here compile? :eek:
Not one I would like to use, that's for sure.
And while the second line will compile, a compiler is free to give a warning instead - g++ does. A static_cast will prevent this warning though.
-
Re: A question regarding cast operator
There might be a little difference in case multiple-inheritance is involved (eg class C : B, A) . When "upcasting", the address of the "Base pointer" might be offset from that of the derived pointer.
static_cast takes it into account.
C-cast, on the other hand, I am unsure. Maybe it does, maybe it doesn't.
I'm not saying the C-cast is wrong, but the fact that I've never really been sure about how C-Cast works in C++ is why I don't use C-cast in C++ ...
-
Re: A question regarding cast operator
Quote:
Originally Posted by
nuzzle
I've never found a reason to use the conversion operator so I may be wrong here but if you define a conversion operator why do you need to cast at all? Why don't you simply do,
B* pB = a; // #3
All of #1, #2 and #3 work but if you remove the conversion operator from A none of them will. That means they're all functionally equivalent in this case. They all simply invoke the conversion operator.
Generally they're not equivalent though. When you cast explicitly you're recommended to use one of the "new" more targeted casts. In this case it would be static_cast.
I agree with you. If someone uses B* pB = (B*)a, then it is not good to use C style casting in C++. If someone uses B* pB = static_cast<B*>(a), then there is a dilemma that why would cast operator is equivalent to static_cast instead of dynamic_cast or reinterpret_cast?
-
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
If someone uses B* pB = static_cast<B*>(a), then there is a dilemma that why would cast operator is equivalent to static_cast instead of dynamic_cast or reinterpret_cast?
Not dynamic_cast because you are not casting from a base class pointer to a derived class pointer (or you are, but you are absolutely sure, on pain of death, that the base class pointer points to an object of that derived class). Since you have defined the conversion, it then makes sense for it to be static_cast rather than reinterpret_cast since the conversion is supposedly "safe" (i.e., when reading the code, your mental alarm bells are supposed to ring louder when you see a reinterpret_cast than a static_cast, at least in theory).
-
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
Not dynamic_cast because you are not casting from a base class pointer to a derived class pointer (or you are, but you are absolutely sure, on pain of death, that the base class pointer points to an object of that derived class). Since you have defined the conversion, it then makes sense for it to be static_cast rather than reinterpret_cast since the conversion is supposedly "safe" (i.e., when reading the code, your mental alarm bells are supposed to ring louder when you see a reinterpret_cast than a static_cast, at least in theory).
Why are you so sure I am not casting from a base class pointer to a derived class pointer? I can design my cast operator like a dynamic casting operator. Also I don't really follow why you would think my cast operator can NOT be a reinterpret_cast? Any more explainations? Thanks.
-
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
Why are you so sure I am not casting from a base class pointer to a derived class pointer?
In your example, A and B are not related through inheritance. Furthermore, I did give leeway, as per the part in parentheses.
Quote:
Originally Posted by LarryChen
I can design my cast operator like a dynamic casting operator.
That would be completely pointless since you might as well just use dynamic_cast. (Also, see my answer concerning reinterpret_cast.)
Also, you need to be precise in your terminology. Your operator B* member is an example of a conversion function, also known as a conversion operator, but when I read "cast operator", I think of static_cast, dynamic_cast, or Boost's lexical_cast, in which case I would expect a function template from you that generically performs some kind of type coercion rather than a specific case of a conversion function.
Quote:
Originally Posted by LarryChen
Also I don't really follow why you would think my cast operator can NOT be a reinterpret_cast?
Because even if you used reinterpret_cast to implement the conversion function, the fact that you specifically implemented the conversion means that the cast should be relatively safe, hence static_cast is expected.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
In your example, A and B are not related through inheritance. Furthermore, I did give leeway, as per the part in parentheses.
That would be completely pointless since you might as well just use dynamic_cast. (Also, see my answer concerning reinterpret_cast.)
Also, you need to be precise in your terminology. Your operator B* member is an example of a conversion function, also known as a conversion operator, but when I read "cast operator", I think of static_cast, dynamic_cast, or Boost's lexical_cast, in which case I would expect a function template from you that generically performs some kind of type coercion rather than a specific case of a conversion function.
Because even if you used reinterpret_cast to implement the conversion function, the fact that you specifically implemented the conversion means that the cast should be relatively safe, hence static_cast is expected.
First of all, it is my bad I used wrong terminology like cast operator in my last post. But I would call it conversion operator(is conversion function equivalent to conversion operator?).
Secondly, I agree it is pointless to use a convesion operator as a dynamic_cast. But why'd you think reinterpret_cast is less safe than static_cast? I think reinterpret_cast and static_cast just serve in different scenario. Thanks.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
LarryChen
to use a convesion operator as a dynamic_cast.
In principle you can't.
A conversion operator is something you define and a dynamic_cast is defined by the language.
And see my post #5 where I explain that if you define a conversion operator you don't need to cast at all.
If you cast you're overruling the C++ type system and if you do that you're responsible for what happens. Leave it to the next guy find that strange bug. :)
-
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
But I would call it conversion operator(is conversion function equivalent to conversion operator?).
Yes. Conversion function is the C++ standard's term.
Quote:
Originally Posted by LarryChen
But why'd you think reinterpret_cast is less safe than static_cast?
Because the conversion performed by reinterpret_cast is usually implementation defined, so the reader of the code has more cause to wonder if it is correct to use the cast in the first place. In the case of a conversion function, you would not even need to explicitly write the cast (but see my comment below), so the conversion is already supposed to be well defined, thus using reinterpret_cast does not make sense.
Quote:
Originally Posted by nuzzle
And see my post #5 where I explain that if you define a conversion operator you don't need to cast at all.
Unless you declare the conversion function as explicit.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
Unless you declare the conversion function as explicit.
Only available for C++11, unfortunately. In good old' C++98, you have to use a "proxy trick" :thumbd:
-
Re: A question regarding cast operator
Quote:
Originally Posted by
nuzzle
In principle you can't.
A conversion operator is something you define and a dynamic_cast is defined by the language.
And see my post #5 where I explain that if you define a conversion operator you don't need to cast at all.
If you cast you're overruling the C++ type system and if you do that you're responsible for what happens. Leave it to the next guy find that strange bug. :)
What did you mean "a dynamic_cast is defined by the language"? A even more interesting example is in the following,
Code:
class D;
class B
{
public:
operator D*();
virtual void foo(){cout<<"B"<<endl;}
};
class D : public B
{
public:
virtual void foo(){cout<<"D"<<endl;}
};
B::operator D*()
{
D* pD = dynamic_cast<D*>(this);
return pD;
}
void test(D* pD)
{
if(pD)
pD->foo();
}
int main()
{
B b;
test(b);
return 0;
}
It compiles fine but the conversion just failed. Why? Thanks.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
LarryChen
It compiles fine but the conversion just failed. Why? Thanks.
Because your this points to a B, which is not a D.
-
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
What did you mean "a dynamic_cast is defined by the language"?
That is, it is a language feature, not something you implement.
Quote:
Originally Posted by LarryChen
It compiles fine but the conversion just failed. Why?
What does dynamic_cast do? If you don't understand that, then of course you don't understand why the conversion failed.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
monarch_dodra
Because your this points to a B, which is not a D.
Okey, let me change the function main a little bit,
Code:
int main()
{
D* pD = new D;
B& b = *pD;
test(b);
delete pD;
return 0;
}
This time it works. It looks like I can design my conversion operator as a dynamic_cast operator.
-
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
It looks like I can design my conversion operator as a dynamic_cast operator.
What you have done is implement your conversion function to perform a dynamic_cast. Anyway, what's your point?
-
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
What you have done is implement your conversion function to perform a dynamic_cast. Anyway, what's your point?
Like I already claimed, when we use a conversion operator, we can NOT safely tell it must be a static_cast as you claimed. It could be a static_cast, dynamic_cast or reinterpret_cast.
-
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
Like I already claimed, when we use a conversion operator, we can NOT safely tell it must be a static_cast as you claimed. It could be a static_cast, dynamic_cast or reinterpret_cast.
No. The conversion function could be implemented with a dynamic_cast, reinterpret_cast, or it might not even use a cast at all, but in any case, one would just use it either without a cast (if it is not explicit) or with a static_cast (if it is explicit, or if you wish to emphasize that there is a conversion).
-
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
Yes. Conversion function is the C++ standard's term.
Because the conversion performed by reinterpret_cast is usually implementation defined, so the reader of the code has more cause to wonder if it is correct to use the cast in the first place. In the case of a conversion function, you would not even need to explicitly write the cast (but see my comment below), so the conversion is already supposed to be well defined, thus using reinterpret_cast does not make sense.
Unless you declare the conversion function as explicit.
I think the keyword "explicit" is used in conversion constructor instead of conversion operator. Or do I miss anything here? Thanks.
-
Re: A question regarding cast operator
Okay, LarryChen, since you love your dynamic_cast "counterexample" so much, consider this contrived example:
Code:
#include <iostream>
class Z;
class Y
{
public:
operator Z*();
virtual ~Y() {}
};
class Z : public Y {};
Y::operator Z*()
{
return dynamic_cast<Z*>(this);
}
int main()
{
Z z;
Y& y = z;
std::cout << static_cast<Z*>(y) << std::endl;
}
Compile and run this program. An address should be printed. Now, change the static_cast to a dynamic_cast and attempt to compile. Does it compile? Why not?
Quote:
Originally Posted by LarryChen
I think the keyword "explicit" is used in conversion constructor instead of conversion operator.
As monarch_dodra noted in post #27, this is a C++11 feature. Previously, the common approaches would be to either allow the implicit conversion, which can be problematic, or use a named conversion function instead (e.g., std::string's c_str() function), or for conversion to bool, provide a conversion to void* instead or use the safe bool idiom.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
LarryChen
What did you mean "a dynamic_cast is defined by the language"?
It's a part of the C++ language, a language feature, "dynamic_cast" is keyword, etc.
Have you read this?
The way I understand it, the whole point in having various cast operators (aside from the fact that they were designed to scare you away from using them) is to use a different one in different situations, and express (via your choice) what is it that you're doing. Although, as I said, I personally think such language design is a bit over the top, but hey... People don't have to agree on everything.
Converting to and from hierarchically unrelated types aside, it is also important to understand inheritance, in order to see what some of the operators are doing or are designed for. Namely, inheritance (in the general OO sense, C++ particularities aside) models "is-a" relationship between types (every Dog is-an Animal, but not the other way around).
Another thing to consider is if a (base) class is polymorphic or not, in the strict sense. In C++, it means if it has virtual methods that can be overridden in a derived class.
So, if B is base, and D is derived, you can safely (up)cast from D to B (Dog to Animal), but things get interesting if you want to cast from B to D (Animal to Dog - either the Animal is actually a Dog, or it's something else, say a Cat).
With dynamic_cast, if B is not polymorphic, the compiler will complain, which is IM(H)O, rather aggressive - but that's how the whole thing is designed.
If it is polymorphic, you get to check, at runtime, if you B really is D or not (if not, you get a null pointer, or an exception).
Next, while the article I linked to deemed static_cast useless, I disagree: if you know what's the actual type of the object, you don't need dynamic_cast and RTTI, and static_cast nicely states that. And it doesn't care if the class is polymorphic or not.
It's designated as less safe, but only if you're pulling stunts with it.
You're also avoiding runtime type check overhead of dynamic_cast.
Finally, reinterpret_cast simply does a "binary copy of the value from one pointer to the other". So, using it would seem to communicate to whoever is reading your code that you have rather specific intentions, or, alternatively, that you are really trying to mess with the code.
P.S. Again, I'm not exactly a C++ dev (I just hopped here from C# forums), so if guys you have any objections to share, please do; a chance for me to learn something myself.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
TheGreatCthulhu
Next, while the article I linked to deemed static_cast useless
I'm not sure how you reached that conclusion. The article seems to state what static_cast does, but does not judge its usefulness, as far as I can tell.
I agree with you though, static_cast is BY FAR the cast I use the most.
-
Re: A question regarding cast operator
Sry, not that article, but the one that advocates C-style casts, a few posts back.
Edit: here - #8.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
Okay, LarryChen, since you love your dynamic_cast "counterexample" so much, consider this contrived example:
Code:
#include <iostream>
class Z;
class Y
{
public:
operator Z*();
virtual ~Y() {}
};
class Z : public Y {};
Y::operator Z*()
{
return dynamic_cast<Z*>(this);
}
int main()
{
Z z;
Y& y = z;
std::cout << static_cast<Z*>(y) << std::endl;
}
Compile and run this program. An address should be printed. Now, change the static_cast to a dynamic_cast and attempt to compile. Does it compile? Why not?
As monarch_dodra noted in post #27, this is a C++11 feature. Previously, the common approaches would be to either allow the implicit conversion, which can be problematic, or use a named conversion function instead (e.g., std::string's c_str() function), or for conversion to bool, provide a conversion to void* instead or use the safe bool idiom.
That is indeed a good example. But it doesn't prove what you claimed. It only prove that C++ compiler parses cast operator first and then parses conversion operator. That is why using dynamic_cast won't compile and static_cast will. Thanks.
-
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
But it doesn't prove what you claimed.
It proves that blindly substituting a dynamic_cast for a static_cast just because the conversion function is implemented with dynamic_cast is a wrong thing to do.
Besides, I am merely stating what is the expected practice (refer to my post #34). If you want to do something else, go ahead, but don't blame me if your code ends up getting ridiculed by those who read it.
If you insist, why not show an example program in which invoking a conversion function implicitly or with static_cast does not make sense, whereas using dynamic_cast or reinterpret_cast to invoke that conversion function works and makes sense?
-
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
It proves that blindly substituting a dynamic_cast for a static_cast just because the conversion function is implemented with dynamic_cast is a wrong thing to do.
Besides, I am merely stating what is the expected practice (refer to my post #34). If you want to do something else, go ahead, but don't blame me if your code ends up getting ridiculed by those who read it.
If you insist, why not show an example program in which invoking a conversion function implicitly or with static_cast does not make sense, whereas using dynamic_cast or reinterpret_cast to invoke that conversion function works and makes sense?
Based on your example, I can change a little bit to make even dynamic_cast work. Here is it,
Code:
std::cout << dynamic_cast<Z*>(&y) << std::endl;
It compiles and runs fine and give the same result. Thanks.
-
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
Based on your example, I can change a little bit to make even dynamic_cast work.
Certainly. But now, a reader reading your code would ask why you used dynamic_cast rather than static_cast. What is your reply?
Another reader reading your code would ask why you implemented the conversion function when using dynamic_cast directly would do the job. What is your reply?
EDIT:
If you want something from the standard, take a look at C++11 Clause 12.3.2, the one on conversion functions. In note 116 of that clause it states that "these conversions are considered as standard conversions for the purposes of overload resolution (13.3.3.1, 13.3.3.1.4) and therefore initialization (8.5) and explicit casts (5.2.9)". Guess what? Clause 5.2.9 is about static_cast.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
Certainly. But now, a reader reading your code would ask why you used dynamic_cast rather than static_cast. What is your reply?
Another reader reading your code would ask why you implemented the conversion function when using dynamic_cast directly would do the job. What is your reply?
EDIT:
If you want something from the standard, take a look at C++11 Clause 12.3.2, the one on conversion functions. In note 116 of that clause it states that "these conversions are considered as standard conversions for the purposes of overload resolution (13.3.3.1, 13.3.3.1.4) and therefore initialization (8.5) and explicit casts (5.2.9)". Guess what? Clause 5.2.9 is about static_cast.
Actually my opinion is that when a conversion operator to convert one type to another is defined, we don't need to EXPLICITLY use cast operator. In that case, using cast operator is just redundancy. Thanks.
-
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
Actually my opinion is that when a conversion operator to convert one type to another is defined, we don't need to EXPLICITLY use cast operator. In that case, using cast operator is just redundancy.
Yes, unless the conversion function is declared explicit, or for some reason you really want to emphasize that there is this conversion that is happening. Again, I already stated this in post #34.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
Yes, unless the conversion function is declared explicit, or for some reason you really want to emphasize that there is this conversion that is happening. Again, I already stated this in post #34.
In VS2010, explicit is not supported for conversion function. Is this feature very new? Thanks.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
LarryChen
In VS2010, explicit is not supported for conversion function. Is this feature very new? Thanks.
Well, for the third time in this thread, yes, it has been introduced with C++11.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
monarch_dodra
Well, for the third time in this thread, yes, it has been introduced with
C++11.
How to pronounce C++11? Is it C++ eleven or C++ one one? Is there any service package to enable VS2010 compiler to support C++11? Or I have to wait until next version of VS appears on the market. Thanks.
-
Re: A question regarding cast operator
Quote:
Originally Posted by
TheGreatCthulhu
With dynamic_cast, if B is not polymorphic, the compiler will complain, which is IM(H)O, rather aggressive - but that's how the whole thing is designed.
If it is polymorphic, you get to check, at runtime, if you B really is D or not (if not, you get a null pointer, or an exception).
if a type is not polymorphic then there's nothing to do "dynamically", being the very idea of a dynamic down-cast relevant to polymorphic types only ( BTW, note that up-casting ( or casting to the same type ) does work with both non- and polymorphic types, no runtime check is performed in either case ). Moreover, consider that dynamic cast has a performace cost; in turn, also static_cast has a (much smaller) performance cost with respect to a reinterpret_cast; I think this fact alone can justify distinguishing between the three flavors of casts. AFAIK, note that this is in contrast with C, where pointer casts are always just a reinterpretation of their binary content, hence always a no-op; so actually, a C-coder would be surprised by the behavior of c-casts in c++: yet another reason to not use c-casts in c++ code, or relegating them to well isolated c-sections of a c++ program.
Quote:
Originally Posted by LarryChen
Is there any service package to enable VS2010 compiler to support C++11? Or I have to wait until next version of VS appears on the market. Thanks.
the vs2010 c++11 support is just partially implemented; yes, implementation will continue incrementally along with the next versions of visual studio, take a look here
-
Re: A question regarding cast operator
Quote:
Originally Posted by
superbonzo
if a type is not polymorphic then there's nothing to do "dynamically", being the very idea of a dynamic down-cast relevant to polymorphic types only ( BTW, note that up-casting ( or casting to the same type ) does work with both non- and polymorphic types, no runtime check is performed in either case ).
I understand that. But, I'm talking about language design here. The very name they chose for it - "dynamic_cast" - prevents it from behaving any other way. Imagine for a moment that its not called that, and that it has a more general name. Now, if the class is not polymorphic, and I want to downcast it to a derived type, why should I, the dev, care about that fact? If the compiler is smart enough to figure out it's not a polymorphic type, then it might as well silently replace it with a static_cast instead, right?
So, what C++ does here is it forces its language implementation details onto the developer. I do believe the more low-level stuff you know, the better your understanding of programming is (and, I also believe it can be said for the other direction too), but from the language design standpoint, forcing implementation details on the developer is just wrong. Well, it's the established practices that do that, actually. C++ itself offers an alternative. And I like that: it allows you to make an assessment, and choose what to do in a given situation.
On Wikipedia's RTTI page it says:
Quote:
RTTI is available only for classes which are polymorphic, which means they have at least one virtual method. In practice, this is not a limitation because base classes must have a virtual destructor to allow objects of derived classes to perform proper cleanup if they are deleted from a base pointer.
Which means that a compiler warning caused by a dynamic_cast can eventually warn you that you didn't design your class properly. OK, that's a benefit, but only if you're lucky; besides, there are probably better ways to do it. A compiler warning perhaps? But, ultimately, in C++, this ends up being the responsibility of the programmer.
On the other hand, I also understand that using various cast operators is a way to express your intentions in the code, and that has a certain value. The performance considerations are valid as well.
Quote:
Originally Posted by
superbonzo
Moreover, consider that dynamic cast has a performace cost; in turn, also static_cast has a (much smaller) performance cost with respect to a reinterpret_cast; I think this fact alone can justify distinguishing between the three flavors of casts.
As I said before: since these language tools are already there, I don't think they should be removed from the language; the more tools there are in the toolbox, the better. I am just not convinced they should be used every single time. When the performance cost actually matters - OK. When you want to emphasize that you're doing a particular kind of casting, for some specific reason - OK. But otherwise, I don't see why a general purpose cast operator is bad.
Again, I don't mind disagreement, and appreciate all of your comments on this topic.