Given:
#include <iostream>
#include <functional>
template<class T> // Just for overloading purposes
struct behaviour1 : std::reference_wrapper<T const>
{
using base_t = std::reference_wrapper<T const>;
using base_t::base_t;
// This wrapper will never outlive the temporary
// if used correctly
behaviour1(T&& t) : base_t(t) {}
};
template<class T>
behaviour1(T&&) -> behaviour1<std::decay_t<T> >;
struct os_wrapper : std::reference_wrapper<std::ostream>
{
using std::reference_wrapper<std::ostream>::reference_wrapper;
template<class T>
os_wrapper& operator<<(behaviour1<T> const& v)
{
*this << v.get(); // #1
return *this;
}
template<class U>
os_wrapper& operator<<(U&& t)
{ this->get() << t; return *this; }
};
int main() { os_wrapper(std::cout) << behaviour1(3); }
In line #1, is the indirection actually performed, given that specific use case (a wrapper that is inmediatly unwrapped, and nor copied neither bound to local references except function parameters), or will the compiler just detect that the object is inmediatly unwrapped and just use the original object instead? Which will be a better design otherwise (for example, whether a partial specialization for scalar types that just save a copy of the object will be more efficient)?
I'm interested specifically in gcc
(version 7, -O3 -std=c++17
) although I guess both clang
and gcc
performs similar optimization techniques.