I was looking into how std::tr1::shared_ptr<> provides the ability to cast to bool. I've got caught out in the past when trying to create a smart pointer that can be casted to bool as the trivial solution, ie
operator bool() {
return m_Ptr!=0;
}
usually ends up being implicitly castable to the pointer type (presumably by type promotion), which is generally undesirable. Both the boost and Microsoft implementations appear to use a trick involving casting to an unspecified_bool_type(). Can anyone explain how this mechanism works and how it prevents implicit casting to the underlying pointer type?
The technique described in the question is the safe bool idiom.
As of C++11, that idiom is no longer necessary. The modern solution to the problem is to use the explicit keyword on the operator:
explicit operator bool() {
return m_Ptr != nullptr;
}
The trick works like this. You define all this inside your smart pointer type (in this case, shared_ptr):
private:
struct Tester
{
Tester(int) {} // No default constructor
void dummy() {}
};
typedef void (Tester::*unspecified_bool_type)();
public:
operator unspecified_bool_type() const
{
return !ptr_ ? 0 : &Tester::dummy;
}
ptr_ is the native pointer inside the smart pointer class.
As you can see, unspecified_bool_type is a typedef to a type that cannot be accessed by any external code, since Tester is a private struct. But calling code can use this (implicit) conversion to a pointer type and check whether it is null or not. Which, in C++, can be used as a bool expression.
Usually what it returns is a member pointer. Member pointers can be treated like a bool but don't support many of the implicit conversions which bool does.
Related
I wrote a custom optional class (since I am forced to use C++98 without STL).
It looks like this:
template <typename T>
struct optional {
char value[sizeof(T)];
bool has_value;
T& operator*() {
return *reinterpret_cast<T*>(value);
}
};
The compiler produces the warning dereferencing type-punned pointer will break strict aliasing rules.
What can I do to make this class without UB?
Maybe memcpy should be used, but I don't understand how.
What can I do to make this class without UB?
Use placement-new to create the object.
Call the destructor of the created object in destructor of optional
Do not reinterpret the address of the storage. Use the pointer returned from placement new. This unfortunately means that you need to store the pointer as a member. You can replace the bool since null pointer would signify empty state.
Take care of alignment. This can be quite tricky pre-C++11. You may need to rely on non-standard language features to achieve this. Given a pointer member which has quite strict alignment, and the fact that C++98 has no overaligned types, you might get away with ignoring alignment for most types.
It would be much easier to allocate the object dynamically. Slower, very likely. But simpler and standard conformant.
One way you can avoid the warning is by having a type-discriminating uinion. Unfortunately, in C++98 it would only work for types which do have default constructors.
I.e.:
...
union {
char empty;
T value;
} storage;
bool has_value;
...
// when object is set to value
new (&storage.value) T(/* arg *);
has_value = true;
...
T& operator() {
// check for has_value should be here
return storage.value;
...
~optiona() {
if (has_value) storage.value.~T();
...
This works, because when union is created, the first element is constructed (empty char). When you put value into the optional, you activate a second member of the union (value), and it is well-defined to access it since.
I'm trying to replace a type, typedef'ed from a built-in integral type, used in a large project with a custom class, which would implement some additional functionality like avoiding truncation on assignment etc. But the project extensively uses a conversion like reinterpret_cast<void*>(value). I've done a naive attempt at implementing an operator void*() in my new class, but apparently this doesn't make it possible to reinterpret_cast, only allows to static_cast to void*. Here's the code:
#include <cstdlib>
#include <type_traits>
#define USE_NEW_VALUE_TYPE
#ifdef USE_NEW_VALUE_TYPE
struct Value
{
size_t value;
operator void* () { return reinterpret_cast<void*>(value); }
};
static_assert(std::is_pod<Value>::value,"Value is not POD");
#else
typedef size_t Value;
#endif
int main()
{
Value v{5};
void* p=reinterpret_cast<void*>(v); // This is how the project uses it
}
I thought that if the class is POD, this would allow me to do such things like a reinterpret_cast. But this code gives me a compilation error:
invalid cast from type ‘Value’ to type ‘void*’
So my question is then: how do I add support for such a reinterpret_cast, so that I didn't have to manually switch it to static_cast in every part of the project?
Unfortunately, reinterpret_cast is not designed for this. The reason this works for POD types is #3 on the cppreference website:
A value of any integral or enumeration type can be converted to a pointer type. A pointer converted to an integer of sufficient size and back to the same pointer type is guaranteed to have its original value, otherwise the resulting pointer cannot be dereferenced safely (the round-trip conversion in the opposite direction is not guaranteed; the same pointer may have multiple integer representations) The null pointer constant NULL or integer zero is not guaranteed to yield the null pointer value of the target type; static_cast or implicit conversion should be used for this purpose.
And, I believe §12.3.2 plays a role here:
A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.
In short: User-defined conversions do not participate in resolution of reinterpret_casts.
Possible solutions
1. Explicitly take the address of v:
void* p=reinterpret_cast<void*>(&v);
2. Defined operator void*() as you did, you could write
void *p = v;
Note: This probably opens up a wormhole of problems due to unwanted implicit conversions
3. Use static_cast as you said yourself.
Note: use &v rather than defining operator void*() for the same reason as in No. 2
4. Ideally, but probably unrealistic, fix the underlying design issue requiring casting classes to void
No. 3 might be the least painful solution here.
EDIT for comment
There are two ways here:
1. Use an overloaded address-of operator (operator&). This may not be possible depending on how Value is used.
#include <cstdlib>
struct Value
{
size_t value;
void* operator &() { return reinterpret_cast<void*>(value); }
};
int main()
{
Value v;
void* p=reinterpret_cast<void*>(&v); // This is how the project uses it
}
2. Implement an operator uintptr_t. While this requires verbose double-casting, it transfers the conversion into the Value class, and uintptr_t is guaranteed to be able to hold a void*.
#include <cstdlib>
struct Value
{
size_t value;
operator uintptr_t() { return static_cast<uintptr_t>(value); }
};
int main()
{
Value v;
void* p=reinterpret_cast<void*>(static_cast<uintptr_t>(v)); // This is how the project uses it
// or less verbose
void* p2=reinterpret_cast<void*>(uintptr_t(v));
}
C++ language doesn't allow overrides for reinterpret_cast. See Overloading c++ typecasting (functions)
1) Replace all such casts with helper functions like:
template <class T>
void* integer_to_voidptr(T t)
{
return reinterpret_cast<void*>(t);
}
template <class T>
T voidptr_to_integer(void* p)
{
return reinterpret_cast<T>(p);
}
2) Add non-template overloads or specialize the templates for your POD.
You can change the call sites to a form that works with both casts:
void* p = reinterpret_cast<void*&>(v);
add this character ^
This effectively treats 'v' as an object that holds a void*, which is true in both cases. The automatic lvalue-to-rvalue conversion will insert a de-reference, extracting either the original size_t or the embedded size_t in Value.
This code is equivalent to:
void* p = *reinterpret_cast<void**>(&v);
However there is no way to get reinterpret_cast to call a custom operator on your object; the point of reinterpret_cast is that it's completely invisible.
I'd like to create a wrapper class for a primitive type in C++ so that I can overload functions and operators for it. However, I would otherwise like it to act exactly like the primitive type. For instance, I would like it to be a POD type, so it can be used in structures accessed by (separately compiled) C code, and be implicitly convertible to/from the primitive type. As a concrete example, I'd like something like Boost tribool, but that is a POD with guaranteed sizeof of 1. C++03 compatibility is very desirable, but C++11-only might be useful too.
It's pretty easy to get started with something like this:
struct tribool_pod {
unsigned char value; // can be private in C++11
tribool_pod& operator=(unsigned char v) { value = v; return *this; }
constexpr operator unsigned char() const { return value; }
tribool_pod& operator=(bool v) { value = v ? 1 : 0; return *this; }
constexpr operator bool() const { return value == 1; }
};
Note that there are no user-defined constructors, so that so far it is a POD type. However, I hit the first snag when writing the operators:
constexpr tribool_pod operator!() const {
return value == 0 ? <true-value> :
value == 1 ? <false-value> :
<indeterminate-value>;
}
In this case, what is the best way to create an instance in an expression for things like <true-value>? In C++11, I can use tribool_pod{true}, but is there any way in C++03? If structs in C++03 can only be initialized in a variable declaration, the only way I can think to write constant expressions for things like <true-value> is to refer to a static const tribool_pod (which has external linkage). That has the drawback of not being header-only and is likely less efficient than using the primitive type.
A related problem even in C++11 is that I don't have a conversion from bool to tribool_pod. Obviously, if I add a conversion constructor to tribool_pod, it is no longer a POD.
Is there some trick I'm missing, or is this fundamentally impossible? This seems like an unfortunate consequence of C++ constructors being an all or nothing proposition: Constructors are the only implicit conversion function, but if you define any, one is always called, and you're no longer a POD type. (Or in C++11 terms, it has standard layout, but is not trivial(ly constructible)).
Or maybe I'm worrying too much about POD-ness? If I include conversion constructors and a no-op default constructor, what do I lose? Just super-obscure things like goto over initialization? I figure I can probably assume standard layout (e.g. no padding at the beginning of the object) with C++03 from real-world compilers, even though the spec doesn't guarantee it.
Note: Part of the reason I care about this is because I want the same headers usable from C (with degraded functionality and safety). For example:
#ifdef __cplusplus
struct tribool_pod { unsigned char value; ... };
#else
typedef unsigned char tribool_pod;
#endif
A header-only solution using a block-static special value:
Foo Foo::f()
{
static const Foo special = make_special_foo(); // or "= { 1, 2, 3 };" etc.
return condition ? value : special;
}
I'm trying to implement a C++ class with a value field that can point to anything (a bit like in boost::any). Currently I do the following:
class MyClass {
void* value;
template<typename T>
Myclass(const &T v) {
value = (void*)(new T(v));
}
};
The problem is now to implement a getValue() operation that creates a copy of the inner value with the right type:
template<typename T>
T getValue() {
return *value;
}
Here it cannot work because I'm trying to unreference a void* pointer. I was wondering which cast (static_cast? dynamic_cast? other...) I should use such that *value is properly converted into a T object and an exception is thrown if value was not originally of this type?
Thanks
You cannot dereference a void*, it simply makes no sense. Why not make the class itself generic? Then you can have:
template<typename T>
class MyClass {
T* value;
MyClass(const T& v) {
value = new T(v);
}
T getValue() {
return *value;
}
};
Make sure to create a destructor which deallocates value and also to follow The Rule of Three. You could also make a version of getValue that returns a const T& (const reference to T) to avoid the copy if one is not required.
which cast (static_cast? dynamic_cast? other...) I should use such that *value is properly converted into a T object
If you must do this conversion, then you should use static_cast, which in general is designed to (among other things) reverse any standard conversion. There's a standard conversion from any object pointer type to void*, and your getter reverses it, so use the cast designed for that:
return *static_cast<T*>(value);
You should also either remove the C-style cast from your constructor, or replace that with a static_cast too.
A reinterpret_cast would also work, but is "overkill". In general you should use the cast that is as restrictive as possible while still performing the conversion you need.
and an exception is thrown if value was not originally of this type
You are out of luck there - C++ cannot in general tell what the original type of the object was, once you've cast the pointer to void*. Your code relies on the caller to call getValue with the correct type. For example, consider what happens if the original type was char -- that's just one byte in C++, there is no room set aside for any type information that would allow the compiler to check the cast in getValue.
dynamic_cast does check types in some limited circumstances, but since your template is fully generic, those limited circumstances might not apply.
If you don't like this, you could change your class to store, in addition to the object pointer, a pointer to a type_info object (resulting from a use of the typeid operator). See the standard header <typeinfo>. You could then compare the type_info object for the type T in the constructor, with the type_info object for the type T in getValue, and throw if they don't match.
As you say, your class is intended to be a bit like boost::any, and getValue is like any_cast. You could consult the source and documentation of that class to see the tricks needed to do what you want. If there were a straightforward way to do it, then boost::any would be a straightforward class!
You can't. C++ doesn't provide that sort of mechanism, at least not directly, not for void*. A void* does not have any information that the computer would need to determine what it is, and attempting to "check" if it is a valid whatever-you-cast-it-to is impossible because there aren't particular flags for that.
There are options, though. The first is to use some kind of universal base class, similar to Java's Object, and derive all of your other classes from that. dynamic_cast will now work the way you want (returning NULL if the object is not a valid object of the class you casted it to).
Another is to simply keep track of what type of object it is yourself. That means augmenting the void* with another value that tells you what you need to cast it to.
But really, neither of these things strike me as good ideas. I think there is almost-definitely some other aspect of your design that should be changed rather than using these. Using templates, as #EdS. suggests, is a very good option, for example.
I'd like to declare a member function pointer in C++, that returns the same member function pointer type
This doesn't work:
class MyClass {
public:
typedef FunctionPtr (MyClass::*FunctionPtr)();
}
Does someone know a solution?
There's no way to achieve exactly that. In fact, member functions make no difference here: there's no way to declare an ordinary function that returns a pointer to its own function type. The declaration would be infinitely recursive.
In case of an ordinary function you can use the void (*)() type as an "universal" function pointer type (just like void * is often used for data types). For member function pointers that would be void (A::*)() type. You'd have to use reinterpret_cast for that purpose though. However, this usage (a round-trip conversion) happens to be the one when the behavior of reinterpret_cast is defined.
Of course, you'll be forced to use casts to convert the pointer to and from that type. AFAIK, there are elegant template-based solutions with an intermediate temporary template object that does the casting.
You might also want to take a look at this GotW entry.
P.S. Note, that using void * type as an intermediate type for function pointers is prohibited by the language. While such illegal use might appear to be "working" with ordinary function pointers, it has absolutely no chance to work with member function pointers. Member function pointers are normally non-trivial objects with size greater than the size of void * pointer.
AndreyT references the best answer at GotW #57, so I might as well replicate it here:
class MyClass {
public:
struct FunctionPtrProxy;
typedef FunctionPtrProxy (MyClass::*FunctionPtr)();
struct FunctionPtrProxy
{
FunctionPtrProxy(FunctionPtr pp ) : p( pp ) { }
operator FunctionPtr() { return p; }
FunctionPtr p;
}
}
What you're trying to do is not possible - the return type of the function is the type of the function itself, which is not yet known, so it leads to an infinite cycle.