临时值的C ++模板类型推导 [英] C++ Template type deduction for temporary value

查看:99
本文介绍了临时值的C ++模板类型推导的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include <iostream>
#include <vector>
using namespace std;

template <typename T>
void wrapper(T& u)
{
    g(u);
}

class A {};

void g(const A& a) {}
int main()
{
    const A ca;
    wrapper(ca);
    wrapper(A()); // Error
}

我有一个问题,为什么最后一条语句会导致编译器错误.

Hi I have a question on why the last statement gives a compiler error.

:18:10:错误:无法绑定类型的非常量左值引用 'A&'到一个类型为'A'wrapper(A())的右值;

:18:10: error: cannot bind non-const lvalue reference of type 'A&' to an rvalue of type 'A' wrapper(A());

我认为模板类型T将被推导为const A&,因为ca也被推导为const A&.为什么在这种情况下类型推导失败?

I thought that the template type T would be deduced as const A& as the ca is also deduced as const A&. Why the type deduction fails in this case?

推荐答案

我认为模板类型T可以推导出为const A&.因为ca也可以推导出为const A&.为什么在这种情况下类型推导失败?

I thought that the template type T would be deduced as const A& as the ca is also deduced as const A&. Why the type deduction fails in this case?

因为那不是扣减规则的工作原理.他们努力推断出尽可能多的与函数参数类型的匹配.临时不一定是const,它可以绑定到const引用.

Because that's not how the deduction rules work. They strive to deduce as much of a match to the function argument type as possible. A temporary is not necessarily const, it can just bind to a const reference.

但是您的函数模板不接受const引用,而是接受非const左值引用.因此,除非函数参数本身为const(不是),否则不会出现const.

But your function template does not accept by a const reference, instead it accepts by a non-const lvalue reference. So no const is gonna spring up unless the function argument is const itself (which it isn't).

正确的解决方案是使用转发引用(对推导的模板参数的右值引用):

The proper solution is to use a forwarding reference (an rvalue reference to a deduced template parameter):

template <typename T>
void wrapper(T&& u)
{
    g(std::forward<T>(u));
}

现在u可以绑定到任何对象.推导的类型将告诉您函数参数的值类别,使您可以将该类别转发给函数调用g(...),并确保选择了正确的重载.

Now u can bind to any object. And the types deduced will tell you the value category of the function argument, allowing you to forward that category to the function call g(...), and making sure the proper overload is picked.

顺便说一句,如果您好奇的话,如果直接将const添加到临时类型中,您的原始代码将很好地构建.

By the way, in case you are curious, if you add the const directly to the temporary type, your original code will build just fine.

using CA = A const;
wrapper(CA()); // Not an error anymore

现在,u最终是一个A const&,并且可以很好地绑定到临时文件.但这只是好奇,在实践中不太可能有用.使用转发引用.

Now u ends up being a A const& and binds to the temporary just fine. But that is just a curiosity that's unlikely to be useful in practice. Use forwarding references.

这篇关于临时值的C ++模板类型推导的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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