简体   繁体   中英

Forwarding params in C++

I have some class and wrapper around it. For example:

#include <iostream>
#include <string>

template<typename T>
class inner
{
public:
    void f(T& v) { std::cout<<"lvalue: "<<v<<std::endl;}
    void f(T&& v) { std::cout<<"rvalue: "<<v<<std::endl;}
};

template<typename T>
class wrapper
{
public:
    template<typename _T>
    void f(_T&& v) { i.f(std::forward<T>(v)); } //(1)

private:
    inner<T> i;
};

int main()
{
    wrapper<std::string> c;
    //inner<std::string> c;

    c.f("r");

    std::string s = "l";
    c.f(s);
}

In the case when c is inner output is correct:

rvalue: r
lvalue: l

But when c is wrapper output is not correct:

rvalue: r
rvalue: l

Why l-value became r-value?

And what the difference if wrapper 's f definition on line (1) would be:

    template<typename _T>
    void f(_T v) { i.f(std::forward<T>(v)); } //without &&

Because you're doing:

template<typename _T>
void f(_T&& v) { i.f(std::forward<T>(v)); } //(1)
                                  ^
                                  T, not _T

You're always just using T , not the deduced type of v . For added clarity, you're actually doing:

template <typename _T>
void f(_T&& v) {
    i.f(std::forward<std::string>(v));
}

And the type of std::forward<std::string>(v) is string&& .

For your second question:

template<typename _T>
void f(_T v) { i.f(std::forward<T>(v)); } //without &&

Since _T will never deduce as a reference type here, std::forward<T>(v) will be equivalent to std::move(v) - it's just a cast to rvalue reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM