gpt4 book ai didi

临时值的 C++ 模板类型推导

转载 作者:太空狗 更新时间:2023-10-29 19:47:41 26 4
gpt4 key购买 nike

#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
}

您好,我有一个问题,为什么最后一条语句给出编译器错误。

: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?

因为扣除规则不是这样运作的。他们努力推断出尽可能多的与函数参数类型的匹配。临时对象不一定是 const,它可以绑定(bind)到 const 引用。

但是您的函数模板不接受 const 引用,而是接受非 const 左值引用。所以没有 const 会出现,除非函数参数是 const 本身(它不是)。

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

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

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


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

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

现在 u 最终成为一个 A const& 并绑定(bind)到临时的就好了。但这只是一种好奇心,在实践中不太可能有用。使用转发引用。

关于临时值的 C++ 模板类型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49505147/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com