I\'m trying to determine whether a C++ function can be declared in such a way that the return value cannot be ignored (ideally detected at compile time). I tried to declare
Prior to c++17 this approach came to mind:
#include
#include
#include
// proxy object which complains if it still owns the return
// value when destroyed
template
struct angry
{
angry(T t) : value_(std::move(t)) {}
angry(angry&&) = default;
angry(angry const&) = default;
angry& operator=(angry&&) = default;
angry& operator=(angry const&) = default;
~angry() noexcept(false)
{
if (value_) throw std::logic_error("not used");
}
T get() && {
T result = std::move(value_).value();
value_.reset();
return result;
}
boost::optional value_;
};
// a function which generates an angry int
angry foo()
{
return 10;
}
int main()
{
// obtain an int
auto a = foo().get();
// this will throw
foo();
}
Synopsis: rather than return a T, a function returns an angry which will punish the caller by throwing a logic_error if the value is not extracted prior to destruction.
It's a run-time solution, which is a limitation, but at least ought to be caught early in unit tests.
A canny user can of course subvert it:
foo().get(); // won't throw