I have a function:
int foo(void * ptr)
{
// ...
}
Can I syntactically (not with compiler warnings, etc.) in C++11/14 disable passing there pointers other than void *
itself?
For example, now it can be called like:
foo(new int(42));
I need to disable this.
The pointer to void can be used in generic functions in C because it is capable of pointing to any data type. One can assign the void pointer with any data type's address, and then assign the void pointer to any pointer without even performing some sort of explicit typecasting.
Void as a Function Return TypeThe void function accomplishes its task and then returns control to the caller. The void function call is a stand-alone statement. For example, a function that prints a message doesn't return a value. The code in C++ takes the form: void printmessage ( )
After declaration, we store the address of variable 'data' in a void pointer variable, i.e., ptr. Now, we want to assign the void pointer to integer pointer, in order to do this, we need to apply the cast operator, i.e., (int *) to the void pointer variable.
A void pointer can hold address of any type and can be typcasted to any type. Note that the above program compiles in C, but doesn't compile in C++. In C++, we must explicitly typecast return value of malloc to (int *).
I suppose there are many other ways of doing it.
Using template functions is simple (it works with C++98 too)
template <typename X>
int foo (X * ptr);
int foo (void * ptr)
{ return 1; }
int main()
{
int i;
void * vp = &i;
foo(vp); // OK
foo(&i); // linker error
return 0;
}
As pointed by frymode, the preceding solution give a linker error, not a compiler error, and it's better to get a compiler error.
Using delete
(from C++11) we can get a compiler error by using this instead:
template <typename X>
int foo (X ptr) = delete;
Hope this helps.
You can make use of pedantic pointer idiom. Your code should look as bellow. It makes use of the fact that there is no implicit conversions at the higher that one level of indirection:
[live]
int foo_impl(void * ptr, void **)
{
return 0;
}
template <typename T>
void foo(T* t)
{
foo_impl(t, &t);
}
int main()
{
void* pv;
foo(pv);
//foo(new int(2)); // error: error: invalid conversion from 'int**' to 'void**'
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With