Cat*_*kul 8 c++ lambda templates rvalue c++17
为什么&&以下示例中的参数类型不表现为所谓的“通用引用”,即使它似乎处于“推导上下文”中,而是被解释为右值:
auto main() -> int {
using MyFn = void (*)(int &);
MyFn special = [](auto && thing) {}; // compile error, deduced as int && rather than int&
return 0;
}
Run Code Online (Sandbox Code Playgroud)
而我期望等效的以下内容是否有效?
template <typename T> void foo(T &&){};
auto main() -> int {
using MyFn = void (*)(int &);
MyFn specialC = foo;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我怀疑将 lambda 转换为函数指针的一些深奥细节在这里很重要,但到目前为止我还无法弄清楚。
转发参考文献有特殊的扣除规则支持。该规则指出,如果我们需要进行推导T才能与T&&相同U&,则T被推导为U&(因此T&&将是U& (&&),它只是折叠为U&)。
但是,此特殊规则仅适用于某些情况:根据函数调用的参数 ( [temp.deduct.call]/3 ) 推导函数模板模板参数时(在参数是类型 的左值的情况下U,其中您可以想象为U&在获取函数模板的地址时以及将函数模板专门化声明与主模板声明 ( [temp.deduct.type]/10 ) 进行匹配时具有类型“”)。
您的情况不是上述情况,而是推导转换函数模板([temp.deduct.conv])的模板参数的单独情况,它没有转发引用的特殊规则。
转发引用扣除规则不适用的另一个示例如下,因此不会编译:
template <class T>
void foo(void(*)(T&&)) {}
void bar(int&) {}
int main() {
foo(bar);
}
Run Code Online (Sandbox Code Playgroud)
在 lambda 参数中,auto它本身给出了通用类型推导。所以这就是你想要的:
MyFn special = [](auto thing) {};
Run Code Online (Sandbox Code Playgroud)
使用不可复制类型来证明它不是按值传递的演示: https: //godbolt.org/z/5vfWc6c8x
| 归档时间: |
|
| 查看次数: |
455 次 |
| 最近记录: |