How can a variable have 2 data types? If "month" is a variable and it should be take from input with std::cin. What should I do so that the user can enter a string like "January" or enter an integer like 1?
4 Answers
In C++ 17 we got something called std::variant it is basicaly a type safe union to use it you just declare the types you need:
std::variant<int, std::string> data;
data = "Hello!";
data = 13;
// No Compilation Issues
The Hard Part Is When You Want To Retrieve The Data
std::string& text = std::get<std::string>(data):
int& number = std::get<int>(data);
BUT MAKE SURE THE LAST THING YOU DEFINED IT AS IS THE TYPE YOU ARE TRYING TO RETRIEVE MEANING:
data = 13;
std::string& text = std::get<std::string>(data); // Bad Exception Error
A better thing is to use std::get_if
if (auto temp = std::get_if<std::string>(&data);
std::string& text = *temp; // do what ever you want
I Hope this answerd Your Question Happy Coding!
2 Comments
std::visit is generally better.std::variant<int,std::string> for a month and I am also convinced that OP shouldn'tHow can a variable have 2 data types?
It cannot. An object has one type. A single type can represent values of different types (unions,std::variant). However, you do not need it here. Whether the user enters 1 or "January" shouldn't matter, because it is both the same month.
What should I do so that the user can enter a string like "January" or enter an integer like 1?
When you read user input, read it as a std::string. Internally you can use an enum:
#include <iostream>
#include <string>
enum class month { January, February, Mazember};
std::istream& operator>>(std::istream& in, month& m){
std::string temp;
in >> temp;
if (temp == "1" || temp == "January") {
m = month::January;
}
//...
return in;
}
std::ostream& operator<<(std::ostream& out,const month& m) {
if (m == month::January) {
out << "January";
}
//...
return out;
}
int main()
{
month m;
std::cin >> m;
std::cout << m;
}
Comments
The declaration will conflict. You can't declare two different data types with a single identifier. For example, std::string month and int month will throw an error. Look at the following:
#include <iostream>
int main(void) {
int month = 2;
std::string month = "January"; // confliction
}
You'll get something:
error: conflicting declaration 'std::string month'
5 | std::string month = "January";
| ^~~~~
vectors.cpp:4:9: note: previous declaration as 'int month'
4 | int month = 2;
| ^~~~~
You can overload functions, but not variables.
Comments
std::any from c++17 also works.
Here is a little usage example.
//DECLARE ANY VARIABLE.
std::any month;
//GET THE INPUT.
std::string in;
std::cout << "Enter Something : " << std::endl;
std::cin >> in;
//STORE AS AN INTEGER.
if (in == "1")
month = std::stoi(in);
//STORE AS A STRING
if (in == "January")
month = in;
std::stringfor month variable and validate after user enters by checking if it's "January" or "1"intfrom 1 to 12, for instance). Then read the users input as a string and convert what the user entered to whatever internal representation you have chosen.