奇怪的操作符?:与decltype一起使用

Strange operator ?: usage with decltype

本文关键字:decltype 一起 操作符      更新时间:2023-10-16

我正在读一本书,这本书解释了c++的特征,并且有一个来自c++ type_traits头的例子,其中有一个奇怪的?:用法,这里是相应的/usr/include/c++/…文件:

template<typename _Tp, typename _Up>
  static __success_type<typename decay<decltype
                        (true ? std::declval<_Tp>()
                         : std::declval<_Up>())>::type> _S_test(int);
撇开给定声明的目的不谈,在这段代码中,?:操作符的用法让我感到困惑。如果第一个操作数是true,则std::declval<_Tp>()将始终作为求值的结果。声明操作数选择是如何工作的?

编辑:原读于Nicolai M. Josuttis的《c++标准库:教程和参考,第二版》,第125页。但与我的GCC头文件相比,这里给出的形式略有简化。

在表达式true ? std::declval<_Tp>() : std::declval<_Up>()中,总是选择第一个可选项,但整个表达式必须是有效的表达式。所以std::declval<_Up>()必须是有效的,这意味着_Up必须是一个接受零参数的可调用对象。除此之外,_Tp()_Up()必须返回相同的类型(或者其中一种类型必须隐式转换为另一种类型),否则三元迭代器将无法选择返回值。

这种技术被称为SFINAE(替换失败不是错误)。这个想法是,如果模板实例化失败,那么它不是一个错误,这个模板只是被忽略,编译器搜索另一个模板。

这里的想法是?:要求第二个和第三个操作数具有相同的类型,或者一种类型可转换为另一种类型。

否则,函数的实例化将失败,并选择其他重载。