In C# you can use as to convert a type or get null:
Object o = Whatever();
String s = o as String;
Is there a similar easy way to achieve this in C++?
I'm using Visual Studio 2010, if that's important.
[Update]: Remember, there is a very important difference between casting and using as. Casting (at least in C#) will throw an exception if the type does not match:
Object o = null;
String s = (String)o; // Will crash.
In C++, this would be a dynamic_cast, if you had a hierarchy where Object is the parent and String is the child.
Object * p = createMyObject();
String * s = dynamic_cast<String *>(p);
if(s)
{
...
}
Dynamic casting a pointer will return a pointer to the object if the cast is possible, or a null pointer if not.
Also, dynamic casting a reference will return a reference to the object if the cast is possible, or throw an exception.
In C++ there is no base object class, so in general there is no way of doing this. You can however do it for specific hierarchies:
struct A {
virtual ~A() {}
};
struct B : public A {
};
A * p = Something(); // Something() may return an A * or a B *
B & b = dynamic_cast <B&>(*p);
The dynamic cast will throw an exception if p does not point at something that can safely be converted to a B reference.
Use dynamic_cast<type>(), but it will only work with pointers, not static objects.
From what I can read from: C# Programmer's Reference: AS the as operator performs the same task as dynamic_cast in C++.
In C# the as keyword converts a value to another type. There is code that supports this conversion (probably in the C# runtime). This is not a cast.
For the most part you can't use dynamic_cast or any other kind of cast in C++ to accomplish this, because casts and conversions are not the same thing. I say 'for the most part' because some types can be converted using static_cast, to convert an int to a float but this is still a conversion, not a cast. Also, if you have introduced a type system where everything is derived from an Object-like base class that has this conversion functionality, you might be able to construct a mechanism to support this conversion using dynamic_cast, but you would have had to write this mechanism and this does not seem to be what you're trying to do.
There is nothing built-in to C++ which will do this conversion for you; in other words, there is no C++ equivalent to the C# as keyword.
If you want to perform this conversion, you can often use streams:
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
int main()
{
float f = 42.0f;
stringstream ss;
ss << f;
string s = ss.str();
cout << "Float: " << f << ", String '" << s << "'";
return 0;
}
<sstream> is part of the C++ Standard, so in this regard you might consider it to be 'in the language'.
Using streams to do this conversion can be rather clumsy. Boost offers lexical_cast which can be used to perform these simple conversions with less code:
#include <sstream>
#include <iostream>
#include <boost\lexical_cast.hpp>
using namespace std;
int main()
{
string s = "42";
float f = boost::lexical_cast<float>(s);
cout << "Float: " << f << ", String '" << s << "'";
return 0;
}
Related
For example, if I have:
#include <iostream>
using namespace std;
int main()
{
int b = 1;
int c = 2;
string a = "(b + c)";
cout << (4 * a) << "\n";
return 0;
}
Is it possible to have string a interpreted literally as if the code had said cout << (4 * (b + c)) << "\n";?
No. C++ is not (designed to be) an interpreted language.
Although it's theoretically possible to override operators for different types, it's very non-recommended to override operators that don't involve your own types. Defining an operator overload for std::string from the standard library may break in future. It's just a bad idea.
But, let's say you used a custom type. You could write a program that interprets the text string as a arithmetic expression. The core of such program would be a parser. It would be certainly possible, but the standard library doesn't provide such parser for you.
Furthermore, such parser wouldn't be able to make connection between the "b" in the text, and the variable b. At the point when the program is running, it has no knowledge of variable names that had been used to compile the program. You would have to specify such information using some form of data structure.
P.S. You forgot to include the header that defines std::string.
#include<string>
///...
auto a=std::to_string(b+c);
std::cout<<4*std::stoi(a)<<std::endl;
You can just use std::string and std::stoi.
I have some input which can be simple value or container, packed in std::any. I don't want to use exceptions, so I call noexcept variadic any_cast method which return pointer or nullptr to value of any.
I can verify any cast available with typeid() but I don't want to use it and want to find some alternative. Some typetraits methods, such as decltype, declval or so on. Or simply using std::optional.
But optional seems is still damp and unstable in this case. MSVC compiler the program breaks at runtime in the depths of the std::optional source code.
#include <optional>
#include <any>
#include <utility>
int main() {
int input = 1;
std::initializer_list<int> input2;
input2 = {1,2,3};
std::any any1 = input;
std::any any2 = input2;
std::optional o1 = *std::any_cast<int>(&any1);
std::optional p2 = *std::any_cast<int>(&any2);
// **std::forward<int & __ptr64>**(...) in _Optional_destruct_base return nullptr.
}
Actually, typetraits check will be the best way to test any_cast possibility. But I still confused with c++ metaprogramming.
If you want to stick with std::optional and don't want to use pointers, I think you could write your own function that performs the pointer check for you and return the proper std::optional, something like:
template <typename T>
std::optional<T> get_v_opt(const std::any & a)
{
if(const T * v = std::any_cast<T>(&a))
return std::optional<T>(*v);
else
return std::nullopt;
}
Here in a usage example of how to use such a function:
int main()
{
std::any a(42);
std::optional opt_int = get_v_opt<int>(a);
std::optional opt_str = get_v_opt<std::string>(a);
if(opt_int.has_value())
std::cout << "a is an int with value: " << opt_int.value() << '\n';
else
std::cout << "a is not an int\n";
if(opt_str.has_value())
std::cout << "a is a string with value: " << opt_str.value() << '\n';
else
std::cout << "a is not a string\n";
return 0;
}
Output (for this example):
a is an int with value: 42
a is not a string
Never dereference a pointer without knowing it is non null.
This in general applies to all nullable types; in C++ these are generally types that support unary * and ->.
std::optional o1 = std::any_cast<int>(&any1)?*std::any_cast<int>(&any1):std::optional<int>();
for example.
any dereference of a null nullable type is UB, which can work, crash, or do absolutely anything else as far as the C++ standard is concerned.
But also consider std variant if your set of stored types is closed (does not change).
If I have a std::any of an std::string or an int, how could I cast this into the type that's contained?
std::any has type on it, however I can't use this type to cast.
Example:
#include <any>
#include <iostream>
#include <string>
int main(void) {
std::any test = "things";
std::any test2 = 123;
// These don't work
std::string the_value = (std::string) test;
int the_value2 = (int) test2;
std::cout << the_value << std::endl;
std::cout << the_value2 << std::endl;
}
You use any_cast to do the trick. For example
auto a = std::any(12);
std::cout << std::any_cast<int>(a) << '\n';
You can find more details from cppreference
If you want to dynamically cast the value inside a std::any, you can try
if (a.type() == typeid(int)) {
cout << std::any_cast<int>(a) << endl;
} else if (a.type() == typeid(float)) {
cout << std::any_cast<float>(a) << endl;
}
If you do not have a list of types among which the any holds one, you cannot convert the any to its type and operate on it as its real type.
You can store a type in an any, and an operation in that type as a function pointer on that any. But this must be done at the moment of storage or when you do have a list (possibly with 1 element) of the possible types stored in the any.
C++ does not store sufficient information within an any to permit arbitrary code to be compiled on that type when it stores the value in the any. C++ does not permit full "reification" at runtime.
Type erasing type erasure, `any` questions? Q&A by a stackoverflow user of ill repute gives an example of how to remember some operation on the contents of the any while still forgetting the type stored.
If you do have such a list of possible types, consider using variant. any exists in the narrow window where you do not know the types stored at container design time, but do at both insert and removal.
In that narrow window, you can do runtime tests based off the typeid stored and cast to the known type using any_cast.
Let's assume that A and B are two classes (or structures) having no inheritance relationships (thus, object slicing cannot work). I also have an object b of the type B. I would like to interpret its binary value as a value of type A:
A a = b;
I could use reinterpret_cast, but I would need to use pointers:
A a = reinterpret_cast<A>(b); // error: invalid cast
A a = *reinterpret_cast<A *>(&b); // correct [EDIT: see *footnote]
Is there a more compact way (without pointers) that does the same? (Including the case where sizeof(A) != sizeof(B))
Example of code that works using pointers: [EDIT: see *footnote]
#include <iostream>
using namespace std;
struct C {
int i;
string s;
};
struct S {
unsigned char data[sizeof(C)];
};
int main() {
C c;
c.i = 4;
c.s = "this is a string";
S s = *reinterpret_cast<S *>(&c);
C s1 = *reinterpret_cast<C *>(&s);
cout << s1.i << " " << s1.s << endl;
cout << reinterpret_cast<C *>(&s)->i << endl;
return 0;
}
*footnote: It worked when I tried it, but it is actually an undefined behavior (which means that it may work or not) - see comments below
No. I think there's nothing in the C++ syntax that allows you to implicitly ignore types. First, that's against the notion of static typing. Second, C++ lacks standardization at binary level. So, whatever you do to trick the compiler about the types you're using might be specific to a compiler implementation.
That being said, if you really wanna do it, you should check how your compiler's data alignment/padding works (i.e.: struct padding in c++) and if there's a way to control it (i.e.: What is the meaning of "__attribute__((packed, aligned(4))) "). If you're planning to do this across compilers (i.e.: with data transmitted across the network), then you should be extra careful. There are also platform issues, like different addressing models and endianness.
Yes, you can do it without a pointer:
A a = reinterpret_cast<A &>(b); // note the '&'
Note that this may be undefined behaviour. Check out the exact conditions at http://en.cppreference.com/w/cpp/language/reinterpret_cast
#include <iosteam>
using namespace std;
Class A
{
int k;
public:
int getK() { return k; }
operator int() { return k; }
};
int main()
{
A a;
cout << a.getK() << " " << int(a) << endl;
}
What's the difference, and which one should I use? I'm wondering if typecasting returns a reference and getK returns a copy.
The only difference is that typecasting can be implicit.
int i = a;
Note that c++11 allow you to force cast operator to be explicitly called.
explicit operator int() { return k; }
They are both returning copies. Providing a cast operator usually is for when casting is necessary. For example you might do something like this maybe:
#include <iosteam>
using namespace std;
Class A
{
double k;
public:
A(double v) : k(v) {}
double getK() { return k; }
operator int() { return static_cast<int>(k); }
};
int main()
{
A a(3.14);
cout << a.getK() << " " << int(a) << endl; // 3.14 3
}
In general I avoid cast operators entirely because I prefer explicit casting.
It returns what the return type is. If you cast to a reference, then that's what you get back. What you're doing both times is making a copy.
The "difference" is what your method does. Your "cast" could add 5 to it and then return it. Or anything you want.
As for appropriateness, as chris said in the first comment, it's usually a "is your class a or not?" type question. Operators should be done for common conversions because your class operates as something, not merely to extract something from it. That's why it's a separate function to convert strings to integers, rather than being merely a cast on the string class. Whereas a complex number type can often be cast directly to a double or int, though that strips information from it. That the conversions can be "abused" is actually why some modern languages don't allow operator overloading. Others take the approach of while it can be abused, it can also be awesome. That's the C++ philosophy on most things: give all the tools, let the user do good or bad with them.
I hope that made sense.