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

问题描述

假设我具有函数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 bothcases 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 whycode doesn't compile.

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

07-23 08:10
查看更多