奇怪的运算符?:使用decltype

时间:2016-10-02 09:22:12

标签: c++ decltype

我正在读一本解释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>()作为评估结果。 该declval操作数选择实际上如何工作?

编辑:最初阅读Nicolai M. Josuttis&#34; C ++标准库:教程和参考,第2版。&#34;,第125页。但与我的GCC头文件相比,它以略微简化的形式给出。

2 个答案:

答案 0 :(得分:10)

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

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

答案 1 :(得分:3)

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

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