关于右值、精确传递 (Perfect Forwarding)请教

发布于 2022-09-12 01:13:01 字数 1852 浏览 58 评论 0

刚刚看了篇关于精确传递 (Perfect Forwarding)的文章,有点不理解的请教下大家。

文章中提到:精确传递适用于这样的场景:需要将一组参数原封不动的传递给另一个函数。

我自己写了个测试程序

 #include <iostream>
 #include <string>
 #include <type_traits>
 using namespace std;

/*
template <typename T>
int process_value(T&& val){
   cout << typeid(val).name() << endl;
   return 1;
}
*/

void process_value(int& i) {
 std::cout << "LValue processed: " << i << std::endl;
}
void process_value(const int& i) {
 std::cout << "const LValue processed: " << i << std::endl;
}
void process_value(int &&i) {
 std::cout << "RValue processed: " << i << std::endl;
}
void process_value(const int &&i) {
 std::cout << "const RValue processed: " << i << std::endl;
}

/*
template <typename T> void forward_value(const T& val) {
  cout << "const T&"<<endl;
  process_value(val);
}
*/

template <typename T> void forward_value(T&& val) { 
//      cout << "T&&" <<endl;
        process_value(val); 
}


int main(){
        int a = 0; 
        const int &b = 1; 
        forward_value(a); // int& 
        forward_value(b); // const int& 
        forward_value(2); // int&&

        return 0;
}

结果是:
image.png

请问下:
forward_value(2) 这里常量2不是应该是个右值嘛?

根据上文:精确传递将一组参数原封不动的传递给另一个函数。forward_value(T&& val) 传递给 process_value(val) 的参数不应该还是右值嘛?所以不是应该调用process_value(int &&i)函数嘛?为什么调用的是process_value(int& i)函数?

参考文章链接精确传递 (Perfect Forwarding)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愚人国度 2022-09-19 01:13:01

std::forward函数通过类型推导+引用折叠等机制,最终会将你传入的T所具有的属性原封不动的传递下去,这就是精确传递(也叫做完美转发),move和它是一个层面的东西,仅是推导过程会将传入的T推导(update:推导这里用的不严谨,应该是通过类型萃取获得其原始类型的右值引用类型)为右值引用类型(type)的右值(value category)。
要理解这个东西你要先明白value category的机制 + 模板类型推导的机制 + 引用折叠的机制 + 左值/右值引用的机制,然后你打开任何一个版本的std::move和std::forward,能用上述机制推导出这两个函数是如何达到目的的就算理解了。
不是我刻意要回复的复杂,而是这个问题就是这么麻烦。。。推荐你一本书《effective modern c++》里面的相关章节能帮到你。

久而酒知 2022-09-19 01:13:01
template <typename T> void forward_value(T&& val) { 
        process_value(val); 
//                    ^^^
}

这个 val 是一个左值。

无论 val 是左值引用还是右值引用,val 都是一个左值。

如果期望 val 是右值引用的时候得到一个右值,需要用 process_value(std::forward<T>(val)); (std::forward<utility> 里)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文