Address of and dereference on a pointer - c++

I came across this function in 'The C++ programming language' book.
template<typename In, typename Out>
Out uninitialized_move(In b, In e, Out oo) {
using T = Value_type<Out>; // assume suitably defined type function (§5.4.2.1, §28.2.4)
for (; b!=e; ++b,++oo) {
new(static_cast<void*>(&*oo)) T{move(*b)}; // move construct
b–>~T(); // destroy
}
return oo;
}
The placement new parameter is &*oo
Why does it need &* in that statement
?
Why won't just passing 'oo' work?

In case oo isn't a pointer and has no operator T*() overload, you can't pass it directly as a pointer.
Some class objects, particularly iterators (like std::vector::iterator), implements something like
SomeStuff& SomeClass::operator*(void);
so that they can be "dereferenced" as if they were pointers. This is called operator overloading.
If you want to pass it directly, you must ensure there's such a member function like
SomeClass::operator T*(void);
In this way such objects can be implicitly converted to the corresponding pointers by calling that function. Otherwise you have to "dereference" it and then take the address of the dereferenced object.

Although you are correct about & and * cancelling each other out for pointers, uninitialized_move is a template function, so oo could be of non-pointer type that has a custom dereference operator *, e.g. an iterator.
For types like that an explicit "round-trip" is required to ensure that static_cast is applied to a pointer.

Related

Example of lvalues / rvalues yielded by member access operators

I have found multiple questions regarding the lvalue yielded by the arrow operator and the lvalue or rvalue yielded by the dot operator, but the answers are not quite coherent.
Chapter 4.6 of the book C++ Primer says:
The arrow operator requires a pointer operated and yields an lvalue. The dot operator yields an lvalue if the object from which the member is fetched is an lvalue; otherwise, the result is an rvalue.
Does the author only mean data members, or also member functions that can be used as an lvalue? Can someone give me an example where the behaviour of these two operators differs, and explain why that is?
Please excuse me if this has been answered elsewhere.
The quote is much easier to understand with some examples. I'll start with the "dot" operator first.
The "dot" operator
Lets consider data members first with a simple Person example:
struct Person {
std::string name;
};
In general when people use a struct or class, you'll normally see it accessed through a named-value which will always yield the standard/expected lvalue reference:
auto person = Person{"Foo"}
std::string& name = person.name;
However, this doesn't always have to be an lvalue. This member access through the "dot" operator will propagate the refness of the object being accessed. That means that you can implicitly get an rvalue ref of name if person is an rvalue (XValue):
auto person = Person{"Foo"};
std::string&& name = std::move(person).name;
Try it Online
or as a temporary (PRValue):
// Note: using a function call here so that the reference doesn't dangle
auto consume(std::string&&) -> void;
...
consume( Person{"Foo"}.name );
Try it Online
This is what the quote is referring to when it says:
The dot operator yields an lvalue if the object from which the member is fetched is an lvalue; otherwise, the result is an rvalue.
This value-propagation is somewhat true of member functions as well. Since C++11, it's been possible to ref-qualify member functions -- which will call the appropriate function based on the refness of the underlying object:
class Person {
...
auto get_name() && -> std::string&&;
auto get_name() const & -> const std::string&;
...
private:
std::string m_name;
};
...
auto person = Person{...};
person.get_name(); // calls 'get_name() const &'
std::move(person).get_name(); // calls 'get_name() &&'
Try it Online
Note: Unlike accessing a data member, the result of the function call need not actually match the value-category; this is just used for determining which function to call as a form of overload resolution.
Arrow Operator
For the default arrow operator (e.g. not a custom operator->), it can only operate on pointers. Pointers, unlike references, don't contain the underlying value-category of the pointee; they only know the value category of the pointer itself.
For example, std::moveing a Person* will yield a Person*&& -- which is an rvalue of the pointer, but not of the underlying pointed object. For this reason, dereferencing through operator-> can never yield an rvalue, since the pointee is never known to be an rvalue.
Custom operator-> definitions
The Arrow operator is also interesting because, for a custom class, it can be overloaded by defining operator->() -- but this operator will still be constrained by the same problem as described above!
Any definition of operator-> must return an object which either defines operator->, or is a pointer. This is done because any expression a->b in C++ will recursively call operator-> until it reaches a pointer in order to perform the dereference. As we know from above, a pointer does not contain a value category -- so once we reach this point we cannot get an rvalue.
Even if you were to attempt to combine this with ref-qualified functions, such as:
auto operator->() && -> SomeWrapper<T>;
you still won't be able to propagate the value-category to the reference because eventually it will come back down to a pointer which does not contain a value category.
Preface: the C++ system of value categories is rather abstruse; the terms 'lvalue' and 'rvalue' really aren't the whole story, so if you want the full explanation of value categories in all its technical glory, I advise you to check out https://en.cppreference.com/w/cpp/language/value_category as #Richard Critten said in the question comments.
Now, supposing you have a struct
struct S{
int member {5};
};
, the behaviour of the operators will differ when performing member access on temporary objects—since their addresses cannot be taken, member access can only take the form of the dot operator (since no pointer can be produced for the arrow operator):
int x = S().member; // Ok, x = 5
int x = (&(S()))->member; // Error: cannot take address of temporary object
In this case, S() is an rvalue expression, and we can use the dot operator on it, but there isn't really a way to use the arrow operator on it.
Regarding "member functions that can be used as an lvalue", I'm assuming you mean functions that return an lvalue reference, e.g.
struct S {
int member {5};
int& get_ref()
{
return member;
}
}
where the returned lvalue reference can be written to; I don't believe that there is any functional difference with the normal member access case.

Right cast for a void* pointer

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.

c++ question, about * and ->

when I have a pointer like:
MyClass * pRags = new MyClass;
So i can use
pRags->foo()
or
(*pRags).foo()
to call foo.
Why these 2 are identical? and what is *pRags?
Thank you
Why are these two identical?
They are equivalent because the spec says they are equivalent. The built-in -> is defined in terms of the built-in * and ..
What is *pRags?
It is the MyClass object pointed to by pRags. The * dereferences the pointer, yielding the pointed-to object.
For more information, consider picking up a good introductory C++ book.
In addition to the other answers, the '->' is there for convenience. Dereferencing a pointer to an object every time you access a class variable for function is quite ugly, inconvenient, and potentially more confusing.
For instance:
(*(*(*car).engine).flux_capacitor).init()
vs
car->engine->flux_capacitor->init()
pRags->foo() is defined as syntactic sugar that is equivalent to (*pRags).foo().
the * operator dereferences a pointer. That is, it says that you're operating on what the pointer points to, not the pointer itself.
The -> is just a convenient way to write (*).. and *pRags is the object at the address stored in pRags.
Yes they are identical. -> was included in C (and thus inherited into C++) as a notational convenience.
* in that context is used to dereference a pointer.
Unary * is known as the dereferencing operator. Dereferencing a pointer turns a T* into a T&; dereferencing an object invokes that object type's unary operator* on that object value if one is defined, or gives an error otherwise.
(*pRags) that goes through the pointer pRags and get you whole object, so on that you could use regular dot notation . .
pRags is a pointer of type MyClass. Just like you can have pointers for primitive data types, e.g. int ptr, you can also have pointers to objects and in this case represented by pRags. Now accessing the object "members" is done using the arrow operator (->) or you can use the "." and dereference "*" to access the object's member values. Here a member is a variable inside MyClass. So, foo() would have a definition inside MyClass.

When does boost::bind cast arguments to the required type?

When I use boost::bind to bind parameters to a function - when are they casted to the type required by the function (if an implicit cast is possible)?
How are they stored in the bind_t object? As the type originally passed to bind or as the type required by the function signature?
Specifically:
If I have a function of the signature
void SomeFun(SmartPointer<SomeType>)
and I use bind as
boost::bind(&SomeFun, somePtr)
where somePtr is of type SomeType*, will the bind_t object contain a copy of somePtr stored as a simple pointer or will it be casted to the SmartPointer<SomeType> and be stored as a SmartPointer<SomeType>?
There is an implicit cast from SomeType* to SmartPointer<SomeType>. As opposed to boost::shared_ptr this SmartPointer uses a reference counter in the managed objects, meaning SomeType has to be derived from SmartPointed.
This won't even work as there is no implicit conversion or implicit constructor to shared_ptr from SomeType*.
You should call
boost::bind(&SomeFun, boost::shared_ptr<SomeType>(somePtr))
if somePtr is a pointer you have just allocated with "new" and expect to be deleted later when the last reference of the shared_ptr goes out of scope. If you don't want the pointer to be deleted but you know it will still be valid at the time of the call, and the function must take shared_ptr, you can use a no-op deleter to create the shared_ptr. Either way, it is a shared_ptr, not a pointer or a weak_ptr or anything else you must pass in in this instance.
You say your case is different so we would have to see your actual case or one that matches it closer.
You may be getting confused with the case where the function you pass in is a class member function and you pass in the class instance (the object) as one of the parameters. Here you can pass in a pointer, a reference or a shared_ptr and it can be a const reference if the function is a const-method (similarly pointer-to-const or shared_ptr to const).
That is simply because there are different overloads to boost::bind for all these when the function is a class member function.
Where the conversion is implicit the implicit conversion will happen at the time the function is called. boost::bind is just a template that stored what is passed into it.
Some magic will occur with the first parameter if it is used to call a member function.
Note that sometimes boost::bind will store a boost::ref where the function actually takes a reference.
They are stored as the type passed in.
The conversion will happen when you call the function object returned by bind, NOT when you perform the bind.
Had the shared_ptr constructor NOT been marked explicit in:
template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
then you would have ended up with an interesting bug given this behavior of boost::bind. If you had called the functor only once then everything would be fine and your object would be deleted. If you had called it multiple times then you would have had a double free and use-after-free bug, since the second time you constructed a shared_ptr from your pointer you would be using a pointer which has already been freed.
(I just asked a related question about why boost::bind is implemented this way)

member function pointer which returns same type of member function pointer

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.