stl std::forward

effect:

Agent functions for template parameters forward, and to maintain the parameters of the actual type


example:

#include <iostream>
#include <functional>

void add(int& a, int&& b, int c, int *d) {
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << c << std::endl;
    std::cout << *d << std::endl;
}

void add_proxy(int &a, int &&b, int c, int *d) {
    add(a, std::move(b), c, d);
}

template<typename fun, typename A, typename B, typename C, typename D>
void proxy_template(fun f, A&& a, B&& b, C&& c, D&& d) {
    f(std::forward<A>(a), std::forward<B>(b), std::forward<C>(c), std::forward<D>(d));
}

int main() {
    int a = 1;
    add_proxy(a, 2, 3, &a);
    proxy_template(add, a, 2, 3, &a);
    return 0;
}
add_proxy manual proxy types of call clear

proxy_template 4 parameter method called by the agent of the type of template that regardless of the type of parameters you pass Why, can be forwarded in accordance with its actual type


std :: forward Source:

  template<typename _Tp>
    constexpr _Tp&&
    forward(typename std::remove_reference<_Tp>::type& __t) noexcept
    { return static_cast<_Tp&&>(__t); }
Only a column forward, the other is :: type && __t, which is passed to forward the case to the right value, here being irrelevant

Description:

A && a, passing arguments int a, the parameter a is derived template int & && a (folding reference) -> int & a, so A = int &, a = int &

std :: forward <A> (a) -> std :: forward <int &> (int &), std :: remove_reference <int &> :: type-> int, so the above std :: forward matching source,

std::remove_reference<int&>::type&->int&

So the final code is:

constexpr int& &&forward(std::remove_reference<int&>::type& __t) noexcept {return static_cast<int& &&>(__t):}

constexpr int& forward(std::remove_reference<int&>::type& __t) noexcept {return static_cast<int&>(__t);}

Passed to the template is left value, then pass on the left or value


B && b, passed 3, b is the parameter templates derived int && b, so that B = int, b = int &&

:: Forward std <B> (b) -> std :: Forward <int> (int &) (although b = int &&, although called rvalue references, but only that he has the ability to access a temporary variable references, when subsequent use, which in itself is used as a left value) ,

std :: remove_reference <int> :: type-> int, so the above std :: forward matching source,

std::remove_reference<int>::type&->int&

The final code is:

constexpr int&& forward(std::remove_reference<int>::type& __t) noexcept { return static_cast<int&&>(__t);}

That is passed to the template is the right value, or pass along the right value


B and C consistent


D actual transfer is int *, int * if the entire left as a value point of view, it is consistent with A


Published 140 original articles · won praise 28 · views 180 000 +

Guess you like

Origin blog.csdn.net/qq_16097611/article/details/78944986
Recommended