I'm using an API that accepts void*
in certain functions. I frequently accidentally pass the wrong pointer type to the function, and of course it compiles fine, but doesn't work at runtime.
Is there a way to disable implicit conversion to void*
for pointers to a certain class?
Implicit conversions allow the compiler to treat values of a type as values of another type. There's at least one set of scenarios in which this is unambiguously bad: non-total conversions. That is, converting an A to a B when there exists A s for which this conversion is impossible.
You're return ing the value of int sum by setting a void * address to it. In this case, the address is not valid. But, if you keep that in mind and get the value of sum by casting a void * to int it will work.
An implicit conversion sequence is the sequence of conversions required to convert an argument in a function call to the type of the corresponding parameter in a function declaration. The compiler tries to determine an implicit conversion sequence for each argument.
An implicit conversion from type S to type T is defined by an implicit value which has function type S => T , or by an implicit method convertible to a value of that type. Implicit conversions are applied in two situations: If an expression e is of type S , and S does not conform to the expression's expected type T .
Is there any way to disable implicit conversion to
void*
for pointers to a certain class?
No, you can't prevent the implicit conversion, but you could wrap the API function(s) in proxy functions that checks types at compile time and approve/disapprove them there.
Example:
#include <iostream> #include <string> #include <type_traits> void api(void* p) { // your original API std::cout << "void* " << p << '\n'; } template<class T> void api_wrapper(T* p) { // your wrapper // let constness fail in the original api instead of in the static_assert: using type = std::remove_const_t<T>*; static_assert( // add your approved types here std::is_convertible_v<type, std::ostream*> || std::is_convertible_v<type, std::string*>, "Not an approved type" ); api(p); } int main() { std::string foo; api_wrapper(&std::cout); api_wrapper(&foo); //api_wrapper(&std::cin); // compile time error "Not an approved type" }
If the set of pointer types that you would like to disapprove is very small, then instead of listing all the approved types in the static_assert
, just list the disapproved types and adjust the boolean logic:
static_assert( // add your disapproved types here not std::is_convertible_v<type, std::ostream*> && not std::is_convertible_v<type, std::string*>, "Not an approved type" );
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