using viref_func = std::function<void(int& intref)>;
viref_func f1 = [](int foo) { ++foo; };
viref_func f2 = [](auto foo) { ++foo; };
viref_func f3 = [](int& foo) { ++foo; };
viref_func f4 = [](auto& foo) { ++foo; };
int test(0);
f1(test);
f2(test);
f3(test);
f4(test);
I half and half understand why f1 and f2 are valid (and analogous) code (but not "working as I want it to").
How can I make f1 fail compilation, requiring an int reference?
I don't care much if f2 fail or compiles, but if it compiles, the auto variable should be an int reference and not an int. It becoming an auto int ref would be the preferred way out.
f3 and f4 work as intended.
Addendum: references in std::function are used in my library code in a number of places. I want to make it easy on consumers of said library to catch dumb mistakes. I don't mind adding complexity in the library. I want to avoid making it hard on consumers of the library. A user having "auto" on a parameter rather than "auto&" (or proper_type&) caused a lot of problems at the user, and for me helping to track down the bug.
You can wrap int to be uncopyable, but that requires changes to both the call site and the functions:
#include <functional>
template <typename T>
struct uncopyable
{
T value;
uncopyable(T value) : value(value) {}
uncopyable(const uncopyable &) = delete;
uncopyable(uncopyable &&) = delete;
uncopyable& operator=(const uncopyable &) = delete;
uncopyable& operator=(uncopyable &&) = delete;
};
int main()
{
using viref_func = std::function<void(uncopyable<int>& intref)>;
// viref_func f1 = [](int foo) { ++foo; }; // error as desired
// viref_func f2 = [](auto foo) { ++foo; }; // also an error
viref_func f3 = [](uncopyable<int>& foo) { ++foo.value; };
viref_func f4 = [](auto& foo) { ++foo.value; };
uncopyable<int> test(0);
f3(test);
f4(test);
}
See it on coliru
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