3

I'm coming from node.js and I was wondering if there is a way to do this in C++. What would be the C++ equivalent of:

var string = "hello";
string = return_int(string); //function returns an integer
// at this point the variable string is an integer

So in C++ I want to do something kind of like this...

int return_int(std::string string){
     //do stuff here
     return 7; //return some int
}
int main(){
    std::string string{"hello"};
    string = return_int(string); //an easy and performant way to make this happen?
}

I'm working with JSON and I need to enumerate some strings. I do realize that I could just assign the return value of return_int() to another variable, but I want to know if it's possible to reassign the type of variable from a string to an int for sake of learning and readability.

TeeraMusic
  • 452
  • 1
  • 5
  • 10
  • No, that's not possible (at least not in _"an easy and performant way to make this happen?"_). C++ fixes any variable types at compile time. – πάντα ῥεῖ Jul 23 '16 at 01:06
  • See http://stackoverflow.com/questions/1517582/what-is-the-difference-between-statically-typed-and-dynamically-typed-languages – Sam Varshavchik Jul 23 '16 at 01:07
  • Bear in mind that it's not the same for a language to be statically typed as to be strongly typed. For example: JavaScript is dynamic and weakly, which allows implicit type conversions (like x = "3" + 5). Python is dynamic and strongly, which allows explicit type conversions (either x = "3"+"5" or x=3+5, but not mixed). C++ is static, so as noted, there is not an easy way since it is not the expected behaviour (you must explicitly declare the type of x at compile time) – fr_andres Jul 23 '16 at 01:14
  • Another sidepoint concerns the so-called Hungarian notation, where the name of the variable itself denotes the expected datatype of its contents. This can be helpful, but can be also regarded as a bad practice, since it can lead to confusion in the dynamic languages, and to redundance in the static ones – fr_andres Jul 23 '16 at 01:25
  • Its possible if you use `std::variant` or `boost::variant`, but that means you have declared the variable as either `string` or `int` beforehand. Also it usually is a horrible idea. – Xarn Jul 23 '16 at 08:27

2 Answers2

5

There is nothing in the C++ language itself that allows this. Variables can't change their type. However, you can use a wrapper class that allows its data to change type dynamically, such as boost::any or boost::variant (C++17 adds std::any and std::variant):

#include <boost/any.hpp>

int main(){
    boost::any s = std::string("hello");
    // s now holds a string
    s = return_int(boost::any_cast<std::string>(s));
    // s now holds an int
}

#include <boost/variant.hpp>
#include <boost/variant/get.hpp>

int main(){
    boost::variant<int, std::string> s("hello");
    // s now holds a string
    s = return_int(boost::get<std::string>(s));
    // s now holds an int
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I assume that `boost:::get`, i.e. 3 x `:`, is a typo? – Rudy Velthuis Jul 23 '16 at 08:21
  • OK, with template magic is it possible, but ISTM not nearly as convenient as for languages that have it built in. The ugly cast-like conversions like `boost::get` and `boost::any_cast`, as well as the declaration of the `boost::variant` make it look a little awkward, IMO. – Rudy Velthuis Jul 23 '16 at 08:40
  • @RudyVelthuis it is not template magic that allows this to work. The same logic can be done without templates. `any` basically holds a pointer to a dynamically allocated data block holding the value. Assigning a different value type allocates a new block. `variant` is basically just a type-safe union. – Remy Lebeau Jul 23 '16 at 16:01
2

That is not possible. C++ is a statically typed language, i.e. types can not change. This will not work with auto or any other way. You will have to use a different variable for the int. In C++11 and newer, you can do:

std::string str = "hello";
auto i = return_int(str);

Or:

int i = return_int(str);

Anyway, calling an integer "string" is a little weird, if you ask me.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94