I have been trying to cast a map structure to a void pointer and cast it vice versa.
void addToMap(void *data){
// add some elements to the map
}
map<string, vector<myStruct> > myMap;
addToMap(&myMap);
I am trying to send myMap to addToMap function as an argument and add some elements inside the function. How can I deference the void parameter back to the map structure ?
I know that static_cast can be used to dereference the void type to know types. For instance:
int* a = new int();
void* b = static_cast<void*>(a);
int* c = static_cast<int*>(b);
The above snippet would work, but not in this case I suppose. I have already tried it out for my case, perhaps there has to be another trick.
In addToMap function you can cast the void pointer back to the original type:
void addToMap(void *data){
auto pmap = static_cast<map<string, vector<myStruct> >*>(data);
pmap->insert(...);
}
static_cast is also able to perform all conversions allowed implicitly
(not only those with pointers to classes), and is also able to perform
the opposite of these. It can:
Convert from void* to any pointer type. In this case, it guarantees that if the void* value was obtained by converting from
that same pointer type, the resulting pointer value is the same.
Related
I recently learned that pointers contain two types of information the memory address and the type they point to.
So I know if I have a pointer, then I can tell whether the object it points to is an int or double or any other primitive data type.
My question was if I create an object called myObj and I have a pointer to myObj, then can I tell from the pointer that the thing it points to is an object called myObj? Or will it just say that the pointer points to a non-primitive data type?
It's not correct to say that pointers contain two types of information. In general terms, a pointer (like any variable) has two properties: a type and a value.
The type of a pointer indicates what it contains the address of. So, a pointer to int (aka an int *) contains the address of an int.
The value of a pointer is the address of an actual object. This is the information contained by the pointer.
Using the type information and the value of a pointer, it is possible to do any permitted operations on the object (or variable) the pointer points at.
For example;
int i;
int *p = &i; // p is of type int *, so points at an int.
// This initialisation gives p a value which is the address of i
*p = 42; // p points at i, *p refers to i, so this statement sets i to be 42
There are a few exceptions to the above though.
A void pointer (aka a void *) does not contain type information (void approximately means "does not have a type" in this context) but does have a value.
int i;
void *p = (void *)(&i);
*p = 42; // invalid, since p is a void * - it could point at anything
A pointer may be uninitialised (e.g. defined without being given an initial value). In that case, accessing its value gives undefined behaviour. As does accessing what it points at (since, to access what a pointer points at, it is necessary to access the value of the pointer itself).
A pointer may be initialised or assigned with the value NULL or (equivalently in C++11 or later) nullptr. This is a special value indicating the pointer does not contain the address of an object. Accessing such a non-existent object also gives undefined behaviour.
Things are more complicated with class/struct types. For example, pointer to a polymorphic type can contain the address of any object of that type, and any type derived from it.
A pointer has a type but it is not a type, the type must match your returning obj.
#include<typeinfo>
#include<string>
#include<iostream>
//..
//..
//..
string name = typeid(*myObj).name()
//..
cout<<"Name: "<< name;
//..
This will return the myObj type.
For more information:
http://en.cppreference.com/w/cpp/language/typeid
Given a class named MyObj
class MyObj
{
private:
//....
//....
public:
//....
//....
};
The pointer type would be of type MyObj, and it would point to a MyObj type or derived type if there are inherited classes under MyObj.
int main()
{
MyObj obj;
MyObj *ptr = &obj; //adress contained in the pointer
return 0;
}
It took me a while to figure this out, but the semantics of boost::any are confusing.
With value types, you use it like so:
int value = 100;
boost::any something;
something = value;
//...later...
int value = boost::any_cast<int>(&something);
This code is clear and makes sense, but stores value internally as a copy. This means for larger objects I place inside boost::any, they will be copied. Also any functions that I replace void* with this will expect that the value outside the function is modified when I modify the value contained in the boost::any object (which won't happen, since it copied it).
So if I put pointers into it, things get weird:
int value = 100;
boost::any something;
something = &value;
//...later...
int* value = *boost::any_cast<int*>(&something);
I have to dereference the return value in this case because boost::any_cast returns int**! I also haven't checked but I think this may crash if something.empty() == true. This is just not straightforward at all.
I do not want to store values in my boost::any, I want it to only function on pointers and behave semantically closer to void*. Pointers in, pointers out, with some type-safety mixed in. Essentially what I want is boost::any_pointer, or something like that. Is there a way to prohibit boost::any from accepting anything except pointers? And if not, is there an alternative to boost::any that can give me the semantics I'm looking for?
You are using any_cast wrong:
There are essentially two (three) flavors.
Taking a reference to any and returning a value or reference to the content
Taking a pointer to any and returning a pointer to the content
Examples:
#include <boost/any.hpp>
int main()
{
// Any holding a value
{
boost::any any_value(1);
// Throws bad_any_cast if the content is not 'int' (in this case):
int value = boost::any_cast<int>(any_value);
// Throws bad_any_cast if the content is not 'int' (in this case):
int& reference = boost::any_cast<int&>(any_value);
// Returns a null pointer if the content is not 'int' (in this case):
int* pointer = boost::any_cast<int>(&any_value);
}
// Any holding a pointer (which is nothing else but a value)
{
int integer = 0;
boost::any any_ptr(&integer);
// Throws bad_any_cast if the content is not 'int*' (in this case):
int * pointer = boost::any_cast<int*>(any_ptr);
// Throws bad_any_cast if the content is not 'int*' (in this case):
int*& pointer_reference = boost::any_cast<int*&>(any_ptr);
// Returns a null pointer if the content is not 'int*' (in this case):
int** pointer_pointer = boost::any_cast<int*>(&any_ptr);
}
}
See also: http://en.cppreference.com/w/cpp/experimental/any and http://en.cppreference.com/w/cpp/experimental/any/any_cast
NOTE: I am assuming you want to store pointers in boost::any, since you are looking for something on the lines of boost::any_pointer (though non-existent).
boost::any_cast returns the pointer to the actual value stored inside it (the held object inside holder). So it kind of saves a copy unless you actually want to copy it later.
template<typename ValueType>
ValueType * any_cast(any * operand) BOOST_NOEXCEPT
{
return operand && operand->type() == boost::typeindex::type_id<ValueType>()
? &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
: 0;
}
You can always create a wrapper around boost::any to allow only pointer types:
class MyAny {
public:
template <typename T,
typename = typename std::enable_if<std::is_pointer<std::remove_cv<T>::type>::value>::type>
MyAny(T ptr): any_(ptr) {}
template <typename ValueType>
ValueType operator*() {
return *boost::any_cast<ValueType>(&any_);
}
private:
boost::any any_
};
Above is a rough code, I have not compiled and tested it.
std::enable_if type trait is available in C++11, but can be found in boost as well. It is what that will constrain your MyAny to only pointer types.
Although this is quite an old question, I nevertheless would like to point out a simple misconception [I think] in the preface of the asked questions:
int value = 100;
boost::any something;
something = &value; // 1)
//...later...
int* value = *boost::any_cast<int*>(&something); // 2)
1) This saved "int *" in something.
2) This contains essentially several steps:
"&something" gets the address of something, i.e. return "boost::any *"
"boost::any_cast()" now casts this address to a pointer to an int - which is probably not what void.pointer wanted. And I don't know whether - and if, why - this seems to work.
And then you dereference "*boost::..." this, i.e. cancelling the "&" from the first step again.
What I think, void.pointer wanted to do here, is more along the following line:
int* value = boost::any_cast<int*>(something);
.
PS: I would have liked to put this in a simple comment and not a full-fledged answer - stackoverflow however requires me to collect enough points first, so...
I'm trying to understand how "pointer to member" works but not everything is clear for me.
Here is an example class:
class T
{
public:
int a;
int b[10];
void fun(){}
};
The following code ilustrate the problem and contains questions:
void fun(){};
void main()
{
T obj;
int local;
int arr[10];
int arrArr[10][10];
int *p = &local; // "standard" pointer
int T::*p = &T::a; // "pointer to member" + "T::" , that is clear
void (*pF)() = fun; //here also everything is clear
void (T::*pF)() = T::fun;
//or
void (T::*pF)() = &T::fun;
int *pA = arr; // ok
int T::*pA = T::b; // error
int (T::*pA)[10] = T::b; // error
int (T::*pA)[10] = &T::b; //works;
//1. Why "&" is needed for "T::b" ? For "standard" pointer an array name is the representation of the
// address of the first element of the array.
//2. Why "&" is not needed for the pointer to member function ? For "standard" pointer a function name
// is the representation of the function address, so we can write &funName or just funName when assigning to the pointer.
// That's rule works there.
//3. Why the above pointer declaration looks like the following pointer declaration ?:
int (*pAA)[10] = arrArr; // Here a pointer is set to the array of arrays not to the array.
system("pause");
}
Why "&" is needed for "T::b" ?
Because the standard requires it. This is to distinguish it from accessing a static class member.
From a standard draft n3337, paragraph 5.3.1/4, emphasis mine:
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed
in parentheses. [Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in
parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because
there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to
member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is
&unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. — end note]
For "standard" pointer an array name is the representation of the address of the first element of the array.
Not really. An array automatically converts to a pointer to first element, where required. The name of an array is an array, period.
Why "&" is not needed for the pointer to member function ?
It is needed. If your compiler allows it, it's got a bug. See the standardese above.
For "standard" pointer a function name is the representation of the function address, so we can write &funName or just funName when assigning to the pointer.
The same thing aplies here as for arrays. There's an automatic conversion but otherwise a function has got a function type.
Consider:
#include <iostream>
template<typename T, size_t N>
void foo(T (&)[N]) { std::cout << "array\n"; }
template<typename T>
void foo(T*) { std::cout << "pointer\n"; }
int main()
{
int a[5];
foo(a);
}
Output is array.
Likewise for functions pointers:
#include <iostream>
template<typename T>
struct X;
template<typename T, typename U>
struct X<T(U)> {
void foo() { std::cout << "function\n"; }
};
template<typename T, typename U>
struct X<T(*)(U)> {
void foo() { std::cout << "function pointer\n"; }
};
void bar(int) {}
int main()
{
X<decltype(bar)> x;
x.foo();
}
Output is function.
And a clarification about this, because I'm not sure what exactly your comment is meant to say:
int arrArr[10][10];
int (*pAA)[10] = arrArr; // Here a pointer is set to the array of arrays not to the array.
Again, array-to-pointer conversion. Note that the elements of arrArr are int[10]s. pAA points to the first element of arrArr which is an array of 10 ints located at &arrArr[0]. If you increment pAA it'll be equal to &arrArr[1] (so naming it pA would be more appropriate).
If you wanted a pointer to arrArr as a whole, you need to say:
int (*pAA)[10][10] = &arrArr;
Incrementing pAA will now take you just past the end of arrArr, that's 100 ints away.
I think the simplest thing is to forget about the class members for a moment, and recap pointers and decay.
int local;
int array[10];
int *p = &local; // "standard" pointer to int
There is a tendency for people to say that a "decayed pointer" is the same as a pointer to the array. But there is an important difference between arr and &arr. The former does not decay into the latter
int (*p_array_standard)[10] = &arr;
If you do &arr, you get a pointer to an array-of-10-ints. This is different from a pointer to an array-of-9-ints. And it's different from a pointer-to-int. sizeof(*p_array_standard) == 10 * sizeof(int).
If you want a pointer to the first element, i.e. a pointer to an int, with sizeof(*p) == sizeof(int)), then you can do:
int *p_standard = &(arr[0);
Everything so far is based on standard/explicit pointers.
There is a special rule in C which allows you to replace &(arr[0]) with arr. You can initialize an int* with &(arr[0]) or with arr. But if you actually want a pointer-to-array, you must do int (*p_array_standard)[10] = &arr;
I think the decaying could almost be dismissed as a piece of syntactic sugar. The decaying doesn't change the meaning of any existing code. It simply allows code that would otherwise be illegal to become legal.
int *p = arr; // assigning a pointer with an array. Why should that work?
// It works, but only because of a special dispensation.
When an array decays, it decays to a pointer to a single element int [10] -> int*. It does not decay to a pointer to the array, that would be int (*p)[10].
Now, we can look at this line from your question:
int (T::*pA3)[10] = T::b; // error
Again, the class member is not relevant to understanding why this failed. The type on the left is a pointer-to-array-of-ints, not a pointer-to-int. Therefore, as we said earlier, decaying is not relevant and you need & to get the pointer-to-array-of-ints type.
A better question would be to ask why this doesn't work (Update: I see now that you did have this in your question.)
int T::*pA3 = T::b;
The right hand side looks like an array, and the left hand side is a pointer to a single element int *, and therefore you could reasonably ask: Why doesn't decay work here?
To understand why decay is difficult here, let's "undo" the syntactic sugar, and replace T::b with &(T::b[0]).
int T::*pA3 = &(T::b[0]);
I think this is the question that you're interested in. We've removed the decaying in order to focus on the real issue. This line works with non-member objects, why doesn't it work with member objects?
The simple answer is that the standard doesn't require it. Pointer-decay is a piece of syntactic sugar, and they simply didn't specify that it must work in cases like this.
Pointers-to-members are basically a little fussier than other pointers. They must point directly at the 'raw' entity as it appears in the object.
(Sorry, I mean it should refer (indirectly) by encoding the offset between the start of the class and the location of this member. But I'm not very good at explaining this.)
They can't point to sub-objects, such as the first element of the array, or indeed the second element of the array.
Q: Now I have a question of my own. Could pointer decay be extended to work on member arrays like this? I think it makes some sense. I'm not the only one to think of this! See this discussion for more. It's possible, and I guess there's nothing stopping a compiler from implementing it as an extension. Subobjects, including array members, are at a fixed offset from the start of the class, so this is pretty logical.
The first thing to note is that arrays decay into pointers to the first element.
int T::*pA = T::b;
There are two issues here, or maybe one, or more than two... The first is the subexpression T::b. The b member variable is not static, and cannot be accessed with that syntax. For pointer to members you need to always use the address-of operator:
int T::*pa = &T::b; // still wrong
Now the problem is that the right hand side has type int (T::*)[10] that does not match the left hand side, and that will fail to compile. If you fix the type on the left you get:
int (T::*pa)[10] = &T::b;
Which is correct. The confusion might have risen by the fact that arrays tend to decay to the first element, so maybe the issue was with the previous expression: int *p = a; which is transformed by the compiler into the more explicit int *p = &a[0];. Arrays and functions have a tendency to decay, but no other element in the language does. And T::b is not an array.
Edit: I skipped the part about functions...
void (*pF)() = fun; //here also everything is clear
void (T::*pF)() = T::fun;
//or
void (T::*pF)() = &T::fun;
It might not be as clear as it seems. The statement void (T::*pf)() = T::fun; is illegal in C++, the compiler you use is accepting it for no good reason. The correct code is the last one: void (T::*pf)() = &T::fun;.
int (T::*pA)[10] = &T::b; //works;
3.Why the above pointer declaration looks like the following pointer declaration ?
int (*pAA)[10] = arrArr;
To understand this, we needn't confuse ourselves with member arrays, simple arrays are good enough. Say've we two
int a[5];
int a_of_a[10][5];
The first (left-most) dimension of the array decays and we get a pointer to the first element of the array, when we use just the array's name. E.g.
int *pa = a; // first element is an int for "a"
int (*pa_of_a)[5] = a_of_a; // first element is an array of 5 ints for "a_of_a"
So without using & operator on the array, when we assign its name to pointers, or pass it to function as arguments, it decays as explained and gives a pointer to its first element. However, when we use the & operator, the decay doesn't happen since we're asking for the address of the array and not using the array name as-is. Thus the pointer we get would be to the actual type of the array without any decay. E.g.
int (*paa) [5] = &a; // note the '&'
int (*paa_of_a) [10][5] = &a_of_a;
Now in your question the upper declaration is a pointer to an array's address without the decay (one dimension stays one dimension), while the lower declaration is a pointer to an array name with decay (two dimensions become one dimension). Thus both the pointers are to an array of same single dimension and look the same. In our example
int (*pa_of_a)[5]
int (*paa) [5]
notice that the types of these pointers are the same int (*) [5] although the value they point to are of different array's.
Why "&" is needed for "T::b" ?
Because that's how the language is specified. It was decided not to complicate the language with a member-to-pointer conversion just for the sake of saving a single character even though, for historical reasons, we have similar conversions for arrays and functions.
For "standard" pointer an array name is the representation of the address of the first element of the array.
No it isn't; it's convertible to a pointer to its first element due to an arcane conversion rule inherited from C. Unfortunately, that's given rise to a widespread (and wrong) belief that an array is a pointer. This kind of confusion is probably part of the reason for not introducing similar bizarre conversions for member pointers.
Why "&" is not needed for the pointer to member function ?
It is. However, your compiler accepts the incorrect void main(), so it may accept other broken code.
For "standard" pointer a function name is the representation of the function address, so we can write &funName or just funName when assigning to the pointer.
Again, the function name isn't a pointer; it's just convertible to one.
Why the above pointer declaration looks like the following pointer declaration ?
One is a pointer to an array, the other is a pointer to a member array. They are quite similar, and so look quite similar, apart from the difference which indicates that one's a member pointer and the other's a normal pointer.
Because T on it's own already has a well defined meaning: the type Class T. So things like T::b are logically used to mean members of Class T. To get the address of these members we need more syntax, namely &T::b. These factors don't come into play with free functions and arrays.
A pointer to a class or struct type points to an object in memory.
A pointer to a member of a class type actually points to an offset from the start of the object.
You can think of these kind of pointers as pointers to blocks of memory. These need an actual address and offset, hence the &.
A pointer to function points to the access point of the function in the assembly code. A member method in general is the same as a function that passes a this pointer as the first argument.
That's in crude nut shell the logic behind needing a & to get the address for members and object address in general.
void (*pF)() = fun; //here also everything is clear
It doesn't work because function fun is undefined
int T::*pA = T::b; // error
What is T::b? T::b is not static member. So you need specific object. Instead write
int *pA = &obj.b[0];
Similarly,
int (T::*pA)[10] = &T::b; //works;
It can be compiled. But it will not work as you expected. Make b static or call obj.b to get access to defined member of defined object. We can easily check this. Create conctructor for your class T
class T
{
public:
T() {
a = 444;
}
int a;
int b[10];
void fun(){}
};
On what value points pA ?
int T::*pA = &T::a;
*pA doesn't not point on variable with value 444, because no object has been created, no constructor has been called.
I have created two routines, one to sort a vector in-place:
void Sort(double** vector, unsigned int vectorLength) {
//...
}
and one that returns a new array with the sorted result:
double* Sort(double* vector, unsigned int vectorLength) {
//...
}
Later using the sort method:
double* test = new double[5];
//...
Sort(*test, 5);
I receive the compiler error that 'none of the 2 overloads could convert all the argument types.'
Is not the type double*, a pointer to a double, not fundamentally different to a double**, a pointer to a pointer to a double?
How is this not clear to the compiler?
You get the error because *test expression is neither double* nor double** - it's a double, with no asterisks.
Passing test without dereferencing it would have worked:
double* sorted = Sort(test, 5); // Invokes the second overload
Note that you can sort in place even if you pass a pointer. Using an overload for this that requires an artificial &, works but it makes your API counter-intuitive.
A better approach would be defining a method with the same set of parameters, but a different name, for example
double* Sort(double* vector, size_t vectorLength) {
//...
}
void SortInPlace(double* vector, size_t vectorLength) {
//...
}
Your variable test has type double* and so *double has type double. Which means that you are attempting to pass double which matches neither double* nor double**.
One possibility is that you actually meant to create a sorted copy of the original array:
double* sorted = Sort(test, 5);
But I rather presume, since your call to Sort ignores the return value, that you meant to pass &test to sort in-place.
Sort(&test, 5);
However, that in itself indicates that your interface is badly designed. You would pass &test if you wanted the function to modify test. But you don't. You want the function to modify the array that test refers to. Your in-place sort function can, and should, be implemented by passing a parameter of type double*.
It is my opinion that you are abusing function overloading here. I would recommend that you choose a different design. I would use functions with different names.
Some other comments:
Use size_t for array lengths.
Use const to indicate that an input parameter shall not be modified.
It's very clear, but the expression *test when test has the type double * is the same as test[0], i.e. it's a double and not a pointer at all.
Perhaps you meant &test to take the address of the pointer.
*test goes directly to the value stored in that memory address. So, it goes to the double stored in the address test, which is a pointer to double.
So, you're passing a double value, not a pointer.
Your work would work with either of these two:
Sort(test, 5); // Passes a pointer to double.
or
Sort(&test, 5); // Gives you the address of test. Passes a pointer to a pointer to double.
class A {
public:
std::vector<int> & getIds(const int & item) const {
return ids[item];
}
private:
std::vector<int> * ids;
}
If ids is a pointer on a vector of ints, then why the method getIds, assuming it uses hidden vector's get operator [] by index, why it returns a reference to a vector of ints and not an int as I expect. Just do not understand this.
Could you please help me to convert it to Java? Please do not give minuses, try to help.
ids is presumably assumed to be a pointer to an element of an array of vectors, for instance:
A::A() : ids(new std::vector<int>[100]) { }
This is very poor style.
The declaration std::vector<int> * ids; says that this is a pointer to either a single object of type std::vector<int> or to (the first element of) an array of that type. The fact that operator[] is used on it in the member function shows that the second is the case.
Applying operator[] to a pointer (as in ids[item]) accesses an element (in this case, the element with number item) of the array the pointer points to. The fact that the type of the objects in the array (std::vector<int>) also has an operator[] defined doesn't matter because this code does not call that (you could call operator[] on such an object by adding another indexing operator, like ids[item][2], or by dereferencing the pointer, like (*ids)[2] (which is equivalent to ids[0][2]).
In C and C++, arrays are just pointers (except std::array, which I'm not talking about). The [] notation just hides some pointer arithmetic.
int foo[10]; //foo is essentially and int *
int bar;
bar = *(foo + 3); //This statement is equivalent to the next
bar = foo[3]; //This just means get what's pointed to 3 pointers away from the address foo
A std::vector is a class.
std::vector<int> *ids
just describes a pointer to an instance of std::vector<int>, not to the data that might be contained in it.