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).
Related
Is there a simple way to understand which union member is active?
An example:
union Read_Value{
char ch;
float number;
string str;
}
Suppose a void function reads from an input file stream and initialise Read_Value on the base of the type of the variable read. Assuming I don't know how the function works, how can I understand which of the three member is active?
A bare union cannot tell you which is the active element. You have to keep track of that yourself.
Since C++17 std::variant is the "modern union". It has a index() method that tells you which is the active index. Example from cppreference:
#include <variant>
#include <string>
#include <iostream>
int main()
{
std::variant<int, std::string> v = "abc";
std::cout << "v.index = " << v.index() << '\n';
v = {};
std::cout << "v.index = " << v.index() << '\n';
}
Possible output:
v.index = 1
v.index = 0
Is there a simple way to understand which union member is active?
In general, using a tagged (or discriminated) union. This means storing some metadata (tracking which member is active) alongside the raw union.
The modern solution is indeed std::variant, which does all this for you.
If you don't have C++17 support, don't have it in your standard library's experimental or tr extensions, and for some reason can't use the Boost.variant precursor ... you can still write an old-style tagged union yourself.
I wouldn't call it simple though, at least not to do well.
We're playing some code golf at work. The purpose is to keep the signature of to_upper and return all arguments to upper. One of my colleague proposes this ~~ugly~~ brillant code:
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
std::string operator+(std::string_view& a, int const& b) {
std::string res;
for (auto c : a) {
res += (c - b);
}
return (res);
}
struct Toto {
std::string data;
};
struct Result {
std::string a;
std::string b;
};
std::unique_ptr<Toto> to_upper(std::string_view input_a,
std::string_view input_b) {
auto* res = new Result;
res->a = (input_a + 32);
res->b = (input_b + 32);
auto* void_res = reinterpret_cast<void*>(res);
auto* toto_res = reinterpret_cast<Toto*>(void_res);
return std::unique_ptr<Toto>(toto_res);
}
int main() {
std::unique_ptr<Toto> unique_toto_res = to_upper("pizza", "ananas");
auto* toto_res = unique_toto_res.release();
auto* res = reinterpret_cast<Result*>(toto_res);
std::cout << res->a << std::endl;
std::cout << res->b << std::endl;
return 0;
}
Is this use of reinterpret_cast is fine in terms of portability and UB?
We think that it's ok because we just trick the compiler on types, but maybe there's something we missed.
std::string operator+(std::string_view& a, int const& b)
It might not be exactly disallowed, but defining an operator overload for a standard class in the global namespace is just asking for ODR violations. If you use any libraries and if everyone else thinks this will just be fine, then someone else may also define that overload. So, this is a bad idea.
auto* void_res = reinterpret_cast<void*>(res);
This is entirely unnecessary. You get exactly the same result by reinterpret casting directly to Toto*.
Valid (and portable)
Assuming that lower and upper case are 32 apart isn't an assumption that is portable to all character encodigs. The function also doesn't work as one might expect for characters outside the range of a...z.
Now about the main question. reinterpret_cast a pointer (or reference) to another itself never has UB. It's all about how you use the resulting pointer (or reference).
The example is a bit precarious while the unique pointer owns the reinterpreted pointer because if an exception is thrown, then it would attempt to delete it which would result in UB. But I don't think an exception can be thrown, so it should be OK. Otherwise, you just reinterpret cast back, which is explicitly well defined by the standard in the case the alignment requirement of the intermediate type isn't stricter than the original (which applies to this example).
The program does leak memory.
The only problem here is you have a memory leak. You never delete the pointer after you call release.
You are allowed to use reinterpret_cast to cast an object to an unrelated type. You are just not allowed to access that unrelated type. Going from Result* to Toto* and then back to Result* is okay, and you only access the Result object through a Result*.
When doing T* to U* and then back to T* both T and U need to be object types and U cannot have a stricter alignment then T. In this case both Result and Toto have the same alignment so you are okay. This is detailed in [expr.reinterpret.cast]/7
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.
I know C++ and know the function sizeof itself but I need to write my own sizeof function so please explain how it works exactly? What does it do with the parameter?
sizeof is a compiler built-in operator. It is evaluated at compile-time by the compiler, and there is no runtime code behind it. You cannot write your own.
Asking this is akin to asking how you would write your own version of return.
You haven't provided any meaningful details about what it is you want to do, so it is hard to figure out what you need.
You can "wrap" sizeof by you own template function like
template <typename T> size_t my_sizeof() {
return sizeof(T);
}
and then use it as
size_t s = my_sizeof<int>();
From time to time one can come across a request to implement sizeof-like functionality without using sizeof. Requests like that make no practical sense whatsoever, yet sometimes are used as homework assignments. One can probably do it as follows
template <typename T> size_t my_sizeof() {
T t;
return (char *) (&t + 1) - (char *) &t;
}
which would require a default-constructible T. A less restricting but formally illegal solution (a hack) would be something like
template <typename T> size_t my_sizeof() {
return (char *) ((T *) NULL + 1) - (char *) (T *) NULL;
}
The above implementations implement type-based sizeof.
An attempt to emulate the functionality of value-based sizeof might look as follows
template <typename T> size_t my_sizeof(const T& obj) {
return my_sizeof<T>();
}
but this will not be even remotely equivalent to the built-in sizeof, at least because the built-in sizeof does not evaluate its argument.
Finally, neither of these implementations will produce integral constant expressions (ICE), as the built-in sizeof does. Producing an ICE that way is impossible to achieve in the current version of the language.
In any case this all, of course, is totally devoid of any practical value. Just use sizeof when you want to know the size.
A non-portable way to write your own sizeof() function is to take advantage of how stack-based variables are often laid out in memory:
#include <iostream>
using namespace std;
template <typename T>
int mysizeof(T)
{
T temp1;
T temp2;
return (int)&temp1 - (int)&temp2;
}
int main()
{
cout << "sizeof mysizeof" << endl;
char c = 0; short s = 0; int i = 0; long l = 0;
float f = 0; double d = 0; long double ld = 0;
cout << "char: " << mysizeof(c) << endl;
cout << "short: " << mysizeof(s) << endl;
cout << "int: " << mysizeof(i) << endl;
cout << "long: " << mysizeof(l) << endl;
cout << "float: " << mysizeof(f) << endl;
cout << "double: " << mysizeof(d) << endl;
cout << "long double: " << mysizeof(ld) << endl;
}
See it in action.
A 0-parameter version.
A version that uses one array instead of two variables.
Warning: This was a fun puzzle, but you should never use this in real code. sizeof is guaranteed to work. This is not. Just because it works on this version of this compiler for this platform does not mean it will work for any other.
The real operator takes advantage of being a part of the compiler. Sizeof knows how big each type of variable is because it has to know. If the compiler doesn't know how big each type is, it wouldn't be able to lay your program out in memory.
Edit: Note that all of these flawed examples rely on the original sizeof operator. It's used to space the stack variables, and to create and index array variables.
As already said it is an operator not a function, but additionally it is one of the operators for which operator overloading is not allowed:
Bjarne Stroustrup's C++ Style and Technique FAQ: Why can't I overload dot, ::, sizeof, etc.?
I can think of no conceivable reason why you would want to overload this in any case. If you have an class for which size information other than that which sizeof yields is required, then simply add a member function to provide that information; as for example in std::string:size() which returns the length of the string managed by the object rather than the size of the object which is semantically different; you do not want to monkey with the semantics of sizeof!
sizeof is an C++ operator which yields the number of bytes in the object representation of its operand. Result of sizeof is an implementation-defined constant of type size_t, but should meet the requirements set forth in C++ Standard 5.3.3. You could write your own type traits that will work similar to built-in sizeof operator.
template<typename T> struct get_sizeof;
template<> struct get_sizeof<char> { static const size_t value = 1; };
template<> struct get_sizeof<unsigned char> { static const size_t value = 1; };
template<> struct get_sizeof<int> { static const size_t value = 4; };
template<> struct get_sizeof<long> { static const size_t value = 4; };
// etc.
...
// sample of use
static const size_t size = get_sizeof<int>::value;
char x[get_sizeof<int>::value];
But this have no sense since only creators of the compiler are knows actual values of value for the implementation.
sizeof isn't a function, and you can't write your own version. The compiler works out the type of the argument (unless it's already a type), then substitutes the expression with an integer constant.
I saw this post when searching for a way to get the same functionality as the sizeof operator. It turned out that I implemented a function called bit_sizeof() that looks a lot like the operator sizeof, but which returns the number of bits of a given type instead. I implemented a global template function like this:
#include <limits.h> //For CHAR_BIT
//Global function bit_sizeof()
template<typename TSizeOfType>
constexpr uint32_t bit_sizeof(TSizeOfType)
{
return (sizeof(TSizeOfType) * CHAR_BIT);
}
This function requires the use of the c++11 standard, as it uses the keyword constexpr. Without the keyword constexpr, the function will compile still. But the compiler may not optimize properly and put in a function call at each call site of using the bit_sizeof function. With the use of constexpr, the whole function evaluates to a constant, which in my knowledge should be exactly equivalent to how the sizeof operator works? Correct me if I am wrong. In use I call the function like this, with an added parantesis after the type:
uint32_t uiBitsInType = bit_sizeof(char());
The function can be useful when creating bit masks for example:
uint32_t uiMask = (((uint32_t(0x1) << bit_sizeof(char())) - 0x1) << bit_sizeof(char()));
Which could be more readable than this:
uint32_t uiMask2 = (((uint32_t(0x1) << (sizeof(char) * 0x8)) - 0x1) << (sizeof(char) * 0x8));
Personally I have other uses for this function also.
If he wants to write his own sizeof he just needs to grab the source code of a C++ compiler and go ahead. The source will also show how sizeof can be implemented.
sizeof is evaluated at compile-time (Boost and Loki make use of it). So, I think, it is impossible to write sizeof - complain function for dynamically allocated buffer.
sizeof isn't a function. It's an operator in C.
We can implement its functionality something like follows.
#include <stdio.h>
#define mysizeof(X) \
({ \
__typeof(X) x; \
(char *) (&x+1) - (char*) (&x); \
})
int main()
{
struct sample
{
int a;float b; char c;
};
printf("%d", mysizeof(struct sample));
return 0;
}
Answer : 12
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;
}