开发者

What's the difference between type(myVar) and (type)myVar?

开发者 https://www.devze.com 2023-01-11 19:34 出处:网络
I\'m going through the full tutorial at cplusplus.com, coding and compiling each example manually. Regularly, I stumble upon something that leaves me perplexed.

I'm going through the full tutorial at cplusplus.com, coding and compiling each example manually. Regularly, I stumble upon something that leaves me perplexed.

I am currently learning this section: http://www.cplusplus.com/doc/tutorial/structures/ . There are some 开发者_开发技巧subtleties that could easily be overlooked by only reading the tutorial. The advantage of typing everything by hand is that such details do stand out.

In the above page, there are two sample programs. One has this line:

stringstream(mystr) >> yours.year;

The other one has this line:

(stringstream) mystr >> pmovie->year;

What I don't understand is the difference (if any) between type (myVar) = x; and (type) myVar = x;.

I am not doing the whole tutorial in sequential order. I checked but didn't find this addressed anywhere, though I may have missed it.

  • Is there a difference?
  • Is there a preferred way to do it one way rather than the other?


There is no difference between type(x) and (type)x. These two are completely equivalent. Most people prefer type(x) for classes and (type)x for non-class types, but that's purely up to one's own choice. Both call constructors for classes with one argument x.

The preferred way for classes is type(x), because this allows passing more than one argument to the constructor, as in type(x, y). Trying to apply the other form, (type)x, y will not work: It casts x, and then applies the comma operator and evalutes y in isolation. Parentheses like (type)(x, y) do not help: This will evaluate x and y in isolation using the comma operator and then cast y to type.

For non-class types, such a cast is often too powerful. C++ has static_cast<type>(x) for roughly doing the reverse of an implicit conversion (such as casting base classes to derived classes and casting void* to another pointer), which often is what fits in. See When should static_cast, dynamic_cast and reinterpret_cast be used?.

stringstream is not a function, though. Doing function(x) will call it the function, but doing (function)x is illegal, beause there are two expressions next to each other, with no operator in between.


For those who don't believe this answer, and downvote it on gut feeling, please consult the Standard at 5.2.3/1

A simple-type-specifier (7.1.5) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).


The page you cite is not what I would consider a authority on C++ in general.

Anyway,

(stringstream) mystr >> pmovie->year;

casts a std::string to a std::stringstream object. This is a C-style cast. Rather dangerous if you don't know what you are doing. This would create a stringstream object and the value is extracted to pmovie->year next.

stringstream(mystr) >> yours.year;

Creates an anonymous std::stringstream object and initializes it with mystr and then the value is extracted to pmovie->year. The object vanishes at the end of its lexical scope which in this case would be the ; at the end of the line.

Not much of a difference (as others have noted so far) among the two w.r.t class objects.

On the other hand, with identifiers (of functions/macros) this gets tricky: function (myVar) = x; works irrespective of whether function is an actual function or a macro. However, (function) (myVar) = x; only works for real functions.

Some standard library identifiers are allowed to have both forms (most notably the tolower and friends) and therefore if you want to invoke the function always then you should go for the former.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号