Elementwise perfect forwarding of a member range Perfect forwarding is usually done with std::forward. E.g.,

template&lt;typename T&gt;
void foo( T&amp;&amp; t ) {
    bar(std::forward&lt;T&gt;(t));
}


for some function bar(). Sometimes, only a member of t, say t.x, needs to be forwarded. This is also a solved problem

template&lt;typename T&gt;
void foo( T&amp;&amp; t ) {
    bar(std::forward&lt;T&gt;(t).x);
}


...But what if t has a range member, say t.range, and bar takes an element from said range? E.g.,

template&lt;typename T&gt;
void foo( T&amp;&amp; t ) {
    for (auto&amp; r : t.range)
        bar(???(r));
}


Here, ??? is a placeholder for a cast which forwards the type of r as the type of t itself would be forwarded.

Note that simply writing

template&lt;typename T&gt;
void foo( T&amp;&amp; t ) {
    for (auto&amp;&amp; r : std::forward&lt;T&gt;(t).range)
        bar(r);
}


won't work as r is still named and will always pass by value or l-value reference but never by r-value reference. To solve this I introduce forward_as&lt;T&gt;

////////////////////////////////////////////////////////////////////////////////
/// Forward As
/// 
/// Forwards u of type U as T would be forwarded. I.e., u is forwarded
/// like some t would be forwarded by std::forward&lt;T&gt;(t). The cv-qualifiers of 
/// U are preserved. E.g., forward_as&lt;T, std::string&gt;(u) casts u to:
///
///  (1) std::string&amp; if T is int&amp;
///  (2) std::string&amp; if T is const int&amp;
///  (3) std::string&amp;&amp; if T is int&amp;&amp;
///
/// Analogously, forward_as&lt;T, const std::string&gt;(u) casts u to:
///
///  (1) const std::string&amp; if T is int&amp;
///  (2) const std::string&amp; if T is const int&amp;
///  (3) const std::string&amp;&amp; if T is int&amp;&amp;
/// 
////////////////////////////////////////////////////////////////////////////////
template&lt;typename T, typename U&gt;
auto forward_as( U&amp;&amp; u ) -&gt; std::conditional_t&lt;
        std::is_reference&lt;T&gt;::value, 
        std::remove_reference_t&lt;U&gt;&amp;, 
        std::remove_reference_t&lt;U&gt;&amp;&amp;&gt;
{
    return static_cast&lt;std::conditional_t&lt;
        std::is_reference&lt;T&gt;::value, 
        std::remove_reference_t&lt;U&gt;&amp;, 
        std::remove_reference_t&lt;U&gt;&amp;&amp;&gt;&gt;(u);
}


Note that I use auto with a trailing return type. This is because my compiler is old. It should work just fine with decltype(auto) on a C++14 compliant compiler. Also note that I've chosen to preserve cv-qualifiers of the given type.

Now the problem from before can be solved by

template&lt;typename T&gt;
void foo( T&amp;&amp; t ) {
    for (auto&amp; r : t.range)
        bar(forward_as&lt;T&gt;(r));
}


Direct member forwarding is also possible using forward_as&lt;T&gt;(t.x).

Have I missed any edge cases? Is there an alternative to all of this? Any suggestions for interface/naming/style improvements?

Edit: I've made a code sample. The syntax is slightly more verbose since the ideone compiler only supports C++11. The underlying principle is the same.
I'll start with some direct review of what you've implemented. After the bullets, however, I go into some concerns about whether this should be used. Thanks for the interesting idea; reviewing it made me re-examine several things I thought I already knew.


Like std::forward you should consider making forward_as a constexpr function.
You could avoid some of the pre-C++14 verbosity by using decltype inside forward_as (although the auto return type sounds better still):

    return static_cast&lt;decltype(forward_as&lt;T, U&gt;(u))&gt;(u);

How do you know whether for (auto&amp;&amp; r : t.range) will iterate over objects owned by t?
Admittedly a bikeshed point, I don't like the way the name forward_as&lt;T&gt;(u) reads; perhaps forward_if&lt;T&gt;(u) or even move_if_rvalue&lt;T&gt;(u) would help this not look like it returns an expression of a T-based type.


However like Kerrek SB's comment on the referenced question, I worry about the state of the main object when forwarding or moving its members. What are the rules for doing this safely? Your examples seem to show forwarding only a single member, but what are the rules when forwarding different parts of the same object? What are the code review guidelines to ensure that problems are not introduced in later edits?

To sum up, I mistrust this. It might just be my own lack of familiarity with such a use case. But it also reflects an uncertainty that optimizing for move is likely to be worth it in these cases. If this is actually a bottleneck or potential bottleneck in the code, are there better alternatives? Does bar even overload on r-value types? Should foo receive t.range instead of t, or will std::for_each be able to generate r-values automatically:

    std::for_each(std::begin(t.range), std::end(t.range), bar)


(If so, I haven't figured out the syntax to support it in your sample with bar as a function template. Using instead a struct with overloaded operator(), it appears to suggest we shouldn't assume the range contains r-values.)