In our software we have some functions that return information through lvalue reference parameters, which, in some cases, are irrelevant for the calling code. For that reason, I tried to come up with an object that can be used instead of a previously declared dummy variable, similar to std::ignore with std::tie (cannot fully take advantage of C++17 yet):
namespace detail {
template<typename T>
struct ignorer_impl {
static_assert(std::is_trivially_copyable_v<T> || std::is_default_constructible_v<T>,
"can only be used on trivially copyable types or default constructible types");
alignas(alignof(T)) unsigned char m_buf[sizeof(T)];
constexpr operator T& () noexcept {
return *reinterpret_cast<T*>(m_buf);
}
};
}
template<typename T, typename = void>
struct ignorer : detail::ignorer_impl<T> {};
template<typename T>
struct ignorer<T, std::enable_if_t<std::is_trivially_copyable_v<T>>> : detail::ignorer_impl<T> {};
template<typename T>
struct ignorer<T, std::enable_if_t<!std::is_trivially_copyable_v<T> && std::is_default_constructible_v<T>>> : detail::ignorer_impl<T> {
constexpr ignorer() noexcept(std::is_nothrow_default_constructible_v<T>) {
new (detail::ignorer_impl<T>::m_buf) T{};
}
};
This can then be used like so:
struct X {
double f;
int i;
std::string s;
};
void foo(X& x) {
x.s = "Hello, world!";
}
int main() {
foo(ignorer<X>{});
return 0;
}
Does anybody have suggestions or see anything that's totally bad?
Also, can you come up with a way that would not require me to explicitly provide the type when using the object (using any C++ version)? (I don't think there's a way, but I'll ask anyway :D)