功能模板推导左值参考和通用参考 [英] Function template deduction l-value reference and universal reference

查看:93
本文介绍了功能模板推导左值参考和通用参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我具有函数copy:

template <typename Buf>
void copy(
    Buf&& input_buffer,
    Buf& output_buffer) 
{}

其中input_buffer是通用引用,而output_buffer是l值引用.

In which input_buffer is a universal reference and output_buffer is an l-value reference.

Reference collapsing rules确保input_buffer确实是真的,而不考虑Buf的推导类型是什么,并且output_buffer确实是l值参考.

Reference collapsing rules make sure input_buffer is indeed, regardless of the deduced type of Buf, an universal reference and output_buffer is indeed an l-value reference.

但是,我想知道如何在这里推导Buf类型.

However, I wonder how type Buf is deduced here.

我发现copy传递了一个r值作为input_buffer,(显然是一个l值传递了output_buffer),Buf是一个非引用类型.

I found out that copy is passed an r-value as input_buffer, (and an l-value as output_buffer, obviously) Buf is a non-reference type.

但是,如果我要传递两个l值,则程序不会编译:

If I were to pass two l-values however, the program does not compile:

int i = 4;
int j = 6;

_copy(i, j);

我希望编译器将Buf推导出为int&.遵循引用折叠规则,我希望input_buffer成为l值引用,即& + && -> &output_buffer也成为l值引用; & + & -> &.

I would expect the compiler to deduce Buf to int&. Following the reference collapsing rules, I would expect input_buffer to become an l-value reference, that is, & + && -> &, and output_buffer to become an l-value reference too; & + & -> &.

所以问题是:为什么此代码无法编译?

So the question is: Why doesn't this code compile?

(注意:我不一定要寻求解决问题的方法,而只是寻求解释.)

(Note: I am not necessarily asking for a solution to the problem, but for an explanation.)

如果需要详细说明,请随时提问.

If I need to elaborate, feel free to ask.

如果致电:copy(i, j); GNU GCC编译器提供: 错误:没有匹配的函数可以调用'copy(int& ;, int&)' 注意:候选:模板无效副本(Buf&&,buf&) 注意:模板参数推导/替换失败: 注意:推导了参数'Buf'('int&'和'int')的冲突类型

if call: copy(i, j); GNU GCC Compiler gives: error: no matching function for call to 'copy(int&, int&)' note: candidate: template void copy(Buf&&, buf&) note: template argument deduction/substitution failed: note: deduced conflicting types for parameter 'Buf' ('int&' and 'int')

如果致电: copy<int&>(i, j); 好吧.

推荐答案

a)转发参考的类型推导:

template<class T>
void f(T&& val) {}

当您传递左值T时,

[a.1]被推导为T&.所以你有

[a.1] when you pass Lvalue T is deduced to be T&. So you have

void f(T& && ){} -after reference collapsing-> void f(T&){}

传递Rvalue T时,

[a.2]被推导为T.所以你有

[a.2] when you pass Rvalue T is deduced to be T. So you have

void f(T&& ) {}

b)除转发参考之外的参考类型推导:

b) Type deduction for reference except forwarding reference:

template<class T>
void f(T& param){}

当您传递Lvalue时,T被推导为T. param的类型为T&,但是模板参数为T,而不是T&.

when you pass Lvalue, T is deduced to be T. param has type T& but template argument is T, not T&.

所以下面的代码可以编译

So below code compiles

int i = 10;
copy(20,i);

因为第一个参数的类型推导会返回Buf==int,因为您传递了20个Rvalue. 第二个参数的推论结果也返回Buf==int.所以两者 Buf相同的情况下,代码会编译.

because type deduction for first argument returns Buf==int since you passed 20 Rvalue. And result of deduction for second argument also returns Buf==int. So in both cases Buf is the same, code compiles.

无法编译的代码:

int i=1;
int j=2;
copy(i,j);

第一个参数的推导类型是什么?您正在传递L值,所以Bufint&. 第二次扣减返回Buf==int.这两种推导类型不同,这就是为什么 代码无法编译.

What is deduced type for first argument? You are passing L-value, so Buf is int&. Second deduction returns Buf==int. These two deduced types are not the same, that is why code doesn't compile.

这篇关于功能模板推导左值参考和通用参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆