首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与lambda尾随返回类型不一致

与lambda尾随返回类型不一致
EN

Stack Overflow用户
提问于 2016-11-02 19:13:43
回答 2查看 169关注 0票数 2

考虑使用gcc-7.0.0最新快照的代码:

代码语言:javascript
复制
auto lambda1 = [](auto&& id) -> decltype(id == 10) { return id == 10; };
auto lambda2 = [](auto&& id) -> decltype(auto)     { return id == 10; };

static_assert(!std::experimental::is_detected_v<ResultOfT,decltype(lambda1),std::string>);
//static_assert(!std::experimental::is_detected_v<ResultOfT,decltype(lambda2),std::string>);
// This doesn't even compile!?
auto bb = std::experimental::is_detected_v<ResultOfT,decltype(lambda2),std::string>;

其中ResultOfT只是std::result_of的包装器。

为什么lambda1lambda2在这个意义上不是等价的?

根据我的理解,decltype(auto) at lambda2应该只是decltype(id == 10)的简短形式,但实际上并非如此,那么原因是什么呢?

这是GCC的错误吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-08 14:43:42

标准他说

函数模板可以使用返回类型推断。即使返回语句中的表达式不依赖,也会在实例化时进行扣减。这个实例化不是在SFINAE.的直接上下文中进行的。

所以GCC身上没有什么问题,它遵循了标准,lambda1,而不是,相当于lambda2

票数 0
EN

Stack Overflow用户

发布于 2016-11-02 20:14:47

通过将表达式放入返回类型,允许编译器调用SFINAE。这意味着,如果id == 10不是模板替换后的合法表达式,那么编译错误就不会产生。这允许is_detected确定该表达式是否合法,因此返回基于该确定的值。

但是SFINAE只对函数的签名起作用。对于第二种情况,签名是decltype(auto)。SFINAE无法将返回表达式拉到签名中。因此,如果尝试用id == 10不合法的类型实例化此函数,则只有在实例化该函数时才会捕获该函数。到那时,对SFINAE来说保护你已经太迟了。

decltype(auto)decltype(expression)不完全相同。它们是相似的,但并不完全相同。

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

https://stackoverflow.com/questions/40387970

复制
相关文章

相似问题

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