首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么std::integral_constant<lambda>不像std::integral_常数<function>那样工作呢?

为什么std::integral_constant<lambda>不像std::integral_常数<function>那样工作呢?
EN

Stack Overflow用户
提问于 2022-02-07 17:37:26
回答 1查看 226关注 0票数 7

(与这个问题有关)。

我试图通过unique_ptrstd::integral_constant和lambda结合起来(在C++20中,获取大部分std函数的地址是非法的,我正在寻找一种方便的方法将它们封装在lambda中)。我注意到std::integral_constant的奇怪行为,我无法解释(哥德波特):

代码语言:javascript
复制
#include <type_traits>

template<auto L, class T = decltype(L)>
using constant = std::integral_constant<T, L>;

void dummy(void*);

int main() 
{
    using C1 = constant<&dummy>;
    using C2 = constant<[](void* p){ dummy(p); }>;

    C1()()(nullptr);        // #1 works as expected
    C2()()(nullptr);        // #2 works as expected

    C1()(nullptr);          // #3 unexpectedly works
    C2()(nullptr);          // #4 fails as expected

    return 0;
}

有人能解释为什么第3行会编译吗?这就是std::unique_ptr在幕后使用的内容(当您使用std::integral_constant作为删除器时),这也是为什么我尝试使用lambda而不是函数地址失败的原因。

P.S.第4行出现以下消息失败:

代码语言:javascript
复制
<source>: In function 'int main()':
<source>:17:17: error: no match for call to '(C2 {aka std::integral_constant<const main()::<lambda(void*)>, <lambda closure object>main()::<lambda(void*)>{}>}) (std::nullptr_t)'
   17 |     C2()(nullptr);          // #4 fails as expected
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-07 18:09:37

在对对象执行函数调用时,不仅考虑调用运算符。如果存在具有适当cvref-限定符的函数指针类型(或函数引用类型)的非显式转换函数,则有一个特殊的异常。

在这种情况下,[over.call.object]/2说会产生额外的过载,一个代理调用函数,它以转换的隐式对象指针作为第一个参数,函数指针/引用的参数作为进一步的参数。如果选择此重载,它将使用转换函数将this转换为函数指针/引用,然后使用其余提供的参数调用它。

std::integral_constant有一个到value_type的非显式转换函数,所以如果value_type是一个函数指针/引用,那么只有这样,这个代理调用才会存在,它实质上将对象函数调用转发给存储的函数指针/引用。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71022928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档