gpt4 book ai didi

c++ - 当从仿函数类模板参数推导出(衰减)类型时,完美转发失败。为什么?

转载 作者:行者123 更新时间:2023-12-01 15:13:14 25 4
gpt4 key购买 nike

在下面的示例中,

#include <iostream>
#include <utility>
//okay:
//
template<typename T, typename F>
decltype(auto) runner(T&& t, F f)
{
return f(std::forward<T>(t));
}

//okay:
//
struct runner_t_f {
template<typename T>
void operator()(T&& t)
{
std::cout<<"template op(): "<<t<<'\n';
}
};

template<typename T>
struct runner_t {
void operator()(T&& t) //error: cannot bind 'T' lvalue to 'T&&'
{
std::cout<<"template functor: "<<t<<'\n';
}
};

int main(void)
{
int j{13};

auto res = runner(j, [](int const& x) -> double { //okay
return static_cast<double>(x*x);
});
std::cout<<res<<'\n';

runner_t_f rtf{};
rtf(j);//okay

runner_t<int> rt{};
rt(j);//not okay...why?
//error: cannot bind ‘int’ lvalue to ‘int&&’

return 0;
}

我尝试创建这些 runner使用完美转发的蹦床功能。除了 runner_t 之外的所有编译(并执行) ,失败并在上面的代码中注释了错误。为什么?

我怎么能模拟编译器试图做的事情,以便我能理解哪里出了问题?提前致谢。

最佳答案

由于引用折叠和模板类型扣除规则,转发引用工作。

在一个简单的函数中:

template <typename T>
void foo(T&& t) {}
  • 当被称为 foo(42) , T推导出为 int ,等等T&&变成 int&& : rvalue-reference-to- int .
  • 当被称为 int i = 42; foo(i) , T推导出为 int&T&&变成 int& && .由于您无法引用引用,因此引用折叠规则开始生效并为您留下 int& : lvalue-reference-to- int .

  • 这一切的意义在于:
    template<typename T>
    struct runner_t {
    void operator()(T&& t) //error: cannot bind 'T' lvalue to 'T&&'
    {
    std::cout<<"template functor: "<<t<<'\n';
    }
    };
  • 当您指定 runner_t<int> , T&&变成 int&& ,并且右值引用不能绑定(bind)到 j因为它是一个左值。
  • 如果您改为指定 rt 的类型成为 runner_t<int&>那么 t 的类型将是 int& && , 将折叠为 int& .这可以绑定(bind)到 j .
  • 关于c++ - 当从仿函数类模板参数推导出(衰减)类型时,完美转发失败。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61282215/

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