跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • C++ 模板 SFINAE 问题
未分類
19 6 月 2020

C++ 模板 SFINAE 问题

C++ 模板 SFINAE 问题

資深大佬 : Tony042 9

在读<<C++ Templates>>第二版时,有一个模板问题,代码如下:

模板定义:

#include <utility>  template <typename F, typename... Args, typename = decltype(std::declval<F>()(std::declval<Args &&>()...))> std::true_type isValidImpl(void *);  template <typename F, typename... Args> std::false_type isValidImpl(...);  inline constexpr auto isValid = [](auto f) {     return [](auto &&... args) {         return decltype(isValidImpl<decltype(f), decltype(args) &&...>(nullptr)){};     }; };  template <typename T> struct TypeT {     using Type = T; };  template <typename T> constexpr auto type = TypeT<T>{};  template <typename T> T valueT(TypeT<T>);  constexpr auto isDefaultConstructible = isValid([](auto x) -> decltype((void)decltype(valueT(x))()) {});  

如果一个 lambda 函数不执行是不是就不检查返回类型合法性了呢,比如在执行isDefaultConstructible(type<x>)命令时,会引入一个 lamda 函数,这个 lambda 函数返回值是decltype((void)decltype(valueT(x))()) {}), decltype(valueT(x))()在 x 是 int 的时候合法,导致最终调用第一个isValidImpl函数,x 是 int&的时候不合法,把第一个isValidImpl SFINAE out,调用第二个此优先级isValidImpl函数,即使 isValid 传入的是一个不合法 lambda 函数,但是由于没有使用所以没有检查 lambda 函数合法性,我的理解正确吗?

大佬有話說 (7)

  • 資深大佬 : GeruzoniAnsasu

    这。。 写的啥东西

    强烈建议你自己丢到 clion 里去调一调这是在干什么

    首先莫名其妙的 inline 是哪来的?
    然后最后这个 isDefaultConstructible 是啥意思? 它是一个 is_valid 返回的 lambda,接受任意多个参数

    我觉得这坨面条可能跟你预期的完全不一样

  • 主 資深大佬 : Tony042

    @GeruzoniAnsasu 这个是可以跑通的,只不过用了 lambda 闭包,需要 C++17 及以上标准,已经在 GCC10 和 MSVC 16.9 都测试过了,没问题的,isDefaultConstructible 是一个 lamda 函数,用来返回类型是否有默认构造函数,如果有默认构造函数则返回 std::true_type 否则返回 std::false_type, 用法是 isConstructible(type<int>),当然你也可以再定义一个类型模板 template <typename T>
    using isDefaultConstructibleT = decltype(isDefaultConstructible(type<T>));

  • 主 資深大佬 : Tony042

    @GeruzoniAnsasu 然后这个是 C++ templates 2nd edition 19.4.3 的一个例子,我有个地方不太理解,就发上来一下,至于 inline 我推测作者放在这的位置是为了优化性能,不过 inline 这个还是要看编译器,应该没影响的,这个模板函数看起来确实比较唬人,不过仔细看应该还是可以理解的

  • 主 資深大佬 : Tony042

    @GeruzoniAnsasu 不好意思,我没有把条件说清澈,是我的锅

  • 資深大佬 : GeruzoniAnsasu

    行 8 那用法解决之后

    实际上逻辑就是检查 typename = decltype(std::declval<F>()(std::declval<Args &&>()…)) 合不合法,进一步来说,就只是检查 declval<传进去的那个参数&&>() 合不合法

    这不就跟 stl 的实现一样的

  • 資深大佬 : hankai17

    头晕 好复杂

  • 資深大佬 : wutiantong

    — 如果一个 lambda 函数不执行是不是就不检查返回类型合法性了呢?

    你的这个问题没提对,因为代码中相关处所涉及的并非普通的 lambda 而是 generic lambda,就你的这个问题这两者是完全不同的。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具