【问题标题】:Strange operator ?: usage with decltype奇怪的运算符?:与 decltype 一起使用
【发布时间】:2016-10-02 09:22:11
【问题描述】:

我正在读一本书,它解释了 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&lt;_Tp&gt;() 作为评估结果。 declval 操作数选择实际上是如何工作的?

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

【问题讨论】:

  • 顺便说一句,这本书是什么?
  • 这里重要的是表达式的类型,而不是要计算的部分。
  • 马特说了什么。该表达式用于使用三元条件运算符类型推导机制(您可以阅读它们here)。

标签: c++ decltype


【解决方案1】:

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

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

【讨论】:

  • 它们不必返回完全相同的类型,只要隐式转换序列可用。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 2013-03-13
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多