6

This cast puzzles me:

#include <string>
#include <iostream>
#include <memory>

using namespace std;

int main() {
    string str1 =  (string)"I cast this thing" +  " -- then add this";
    cout << str1 << endl;
}

Can someone explain why this c-style cast to string works (or is allowed)? I compared the generated optimized assembly with that from:

string str1 =  string("I construct this thing") +  " -- then add this";

and they appear to be identical, so I feel like I'm forgetting some c++ semantics that actually allow this kind of cast/construction to be interchanged.

 std::string str2 =  std::string("I construct this thing") +  " -- then add this";
Mike Ellery
  • 2,054
  • 3
  • 21
  • 30
  • 3
    `(T)x` = `T(x)`. The two are **identical** except in name (C-style cast vs function-style cast). – Konrad Rudolph Jan 12 '16 at 17:58
  • 2
    See also: http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used –  Jan 12 '16 at 17:59

3 Answers3

8

A C-style cast will do a const cast and static cast or reinterpret cast whichever is possible.

A static cast will use a user-defined conversion if defined.

std::string has a constructor string(const char *).

The syntaxes std::string("something"), static_cast<std::string>("something") and (std::string)"something" are equivalent. They will all construct a temporary std::string using the std::string::string(const char *) constructor. The only difference between the syntaxes would be when casting pointers.

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
  • makes complete sense...for some reason I always forget about the "valid user defined conversions" with respect to static casting. – Mike Ellery Jan 12 '16 at 18:40
7

Yep, if you have a constructor that takes in a single argument like that it will be used to cast the argument type to the object type. This is why we can pass const char* to functions taking strings.

Converting constructor

4

std::string has a constructor in the form of

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

This acts as a conversion operator. If you cast a string literal to a std::string it will call this constructor and create a temporary std::string

NathanOliver
  • 171,901
  • 28
  • 288
  • 402