I have this function call:
uint32_t func(uint32_t* a, uint32_t b)
I want to call it with an integer literal like this:
func
A helper class:
struct int_ptr {
int v;
operator int *() { return &v; }
};
int foo(int *a, int b);
void bar()
{
foo(int_ptr{0}, 0);
}
This results in a construction of a temporary int_ptr
class, initializing its v
member to 0. This gets passed as a parameter to a function that takes an int *
, and int_ptr
provides a suitable operator *
method that passes the right pointer to the function.
This entire house of cards hinges on the fact that the int_ptr
temporary exists until the end of the function call. You should pick a name for the helper class to underline that fact. If you always use it to pass a pointer to 0 to foo, then spell it out:
struct zero_value_to_foo {
int v=0;
operator int *() { return &v; }
};
int foo(int *a, int b);
void bar()
{
foo(zero_value_to_foo{}, 0);
}
So that using it in other contexts will look to be very much out of place, i.e.
int *p=zero_value_to_foo{};
This compiles, but leaves you with a dangling pointer; but hopefully the "zero_value_to_foo" label gives a honking clue that something is wrong here.
Another little thing you can do to help yourself from misusing this is to use a ref qualifier for the operator:
struct zero_value_to_foo {
int v=0;
operator int *() && { return &v; }
};
With this,
foo(zero_value_to_foo{}, 0);
still compiles, but not this:
zero_value_to_foo zero{};
foo(zero, 0);
The more that can be done to make it difficult to use this except in the context is meant for, the fewer opportunities there are for bugs to creep by.