惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Heimdal Security Blog
C
Check Point Blog
Jina AI
Jina AI
T
Tailwind CSS Blog
IT之家
IT之家
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
S
SegmentFault 最新的问题
U
Unit 42
Cyberwarzone
Cyberwarzone
T
The Blog of Author Tim Ferriss
I
Intezer
V
Visual Studio Blog
月光博客
月光博客
A
Arctic Wolf
L
LINUX DO - 热门话题
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
Threatpost
F
Fortinet All Blogs
Simon Willison's Weblog
Simon Willison's Weblog
酷 壳 – CoolShell
酷 壳 – CoolShell
K
Kaspersky official blog
L
Lohrmann on Cybersecurity
T
Tenable Blog
爱范儿
爱范儿
大猫的无限游戏
大猫的无限游戏
博客园_首页
Recent Announcements
Recent Announcements
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
C
Cybersecurity and Infrastructure Security Agency CISA
P
Privacy International News Feed
The Register - Security
The Register - Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
J
Java Code Geeks
I
InfoQ
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Webroot Blog
Webroot Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The Last Watchdog
The Last Watchdog
AWS News Blog
AWS News Blog
Last Week in AI
Last Week in AI
Spread Privacy
Spread Privacy
云风的 BLOG
云风的 BLOG
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Apple Machine Learning Research
Apple Machine Learning Research
F
Full Disclosure
Vercel News
Vercel News
The Hacker News
The Hacker News

核桃的炼金工坊

2023 韩国游记 C++23: Flat Containers Deducing This Stateful Metaprogramming 推し、燃ゆ Customization Point Object 2020 总结 搞了个 C++ 构建系统 软件设计哲学(NOTE) Paxos Note 关于 cpp 可见性的黑魔法后门 User-defined conversion and Copy elision VIM and Latex Compare Between CRTP and Virtual Interface in C++ Compile Time Reflection in C++11 C++11内存模型 在C++17中的部分新特性 Const Reference of Pointer
一个关于 private member function detect 的 SFINAE 模板
Hawtian Wang · 2019-12-05 · via 核桃的炼金工坊

问题起源于,我要搞一个模板,来检查一个类,是不是有一个特定的回调接口 OnAlarm()。我显然希望在我的模板类里面,直接调用这个 OnAlarm 回调的。但是问题,就这么出现了。我需要一个模板,来检查一个传给构造函数的指针指向的类型,是不是有我需要的 OnAlarm 方法。如果没有的话,我需要使用另一套回调的机制。 问题就出在了这个检查上面。

最开始的时候,我是写成了这个样子的。

template <typename T, typename = void>
struct HasAlarmCallback : std::false_type {};

template <typename T>
struct HasAlarmCallback<T, decltype(std::declval<T>().OnAlarm())>
    : std::true_type {};

这样看起来是没问题的(其实也是没问题的),但是我遇到了第一个问题。

class B {
  void OnAlarm() {}
};

这个模板在 T = B 的时候,会有编译错误,并不能成功的使用 SFINAE。错误的内容大概就是,这里用了一个 private 的函数,然后是不可见的。

(虽然也不知道为什么)

template <typename T, typename = void>
struct HasAlarmCallback : std::false_type {};

template <typename T>
struct HasAlarmCallback<T, decltype(static_cast<T*>(nullptr)->OnAlarm())>
    : std::true_type {};

struct A {
  void OnAlarm(){};
};

class B {
  void OnAlarm(){};
};

int main() {
  HasAlarmCallback<A> a;
  HasAlarmCallback<B> b;
}

在我这样写的时候,代码是可以完美通过编译,并且可以完美运行的。结果也是完美符合预期的。那我就会想呀,为啥我直接像下面样子写就不对了呢~

std::cout << HasAlarmCallback<A>::value << std::endl;
std::cout << HasAlarmCallback<B>::value << std::endl;

!!!这是我百思不得其解的要点!!! 在我这么写的时候,就不 work,会报像最开始那样的编译问题。

template<typename T, typename = void>
struct _HasAlarmCallback {
  static constexpr bool value = false;
};

template<typename T>
struct _HasAlarmCallback<T, decltype(static_cast<T *>(nullptr)->OnAlarm())> {
  static constexpr bool value = true;
};

template<typename T>
struct HasAlarmCallback {
 private:
  static constexpr _HasAlarmCallback<T> foo{};

 public:
  static constexpr bool value = _HasAlarmCallback<T>::value;
};

我最后发现,如果需要我构造一个实例才能解决这个问题的话,那我就构造一个。 嗯… 虽然… 不知道为啥… 反正是 work 了…

如果有人看到,然后知道为什么的话… 请告诉我!谢谢了!