c++ - 将语法与匿名模板类型混淆?

标签 c++ c++11

template <class T, class U> decltype(*(T*)(0) * *(U*)(0)) mul(T x, U y) {
   return x * y;
}

这段代码取自 Stroustrup 的 C++11 FAQ .我明白它的作用,就是将两个不同类型的对象相乘。令我困惑的是模板参数和函数定义之间的语法。 decltype 内部发生了什么?我认为它正在取消引用初始化为 0 的未命名 T 指针,并将其乘以以相同方式取消引用和初始化的未命名 U 指针。我说得对吗?

好吧,如果这是正在发生的事情,那么指针、解引用和额外的括号的使用不是多余的吗?我不能在保持预期效果的同时初始化这样的类型吗?:

template <class T, class U> decltype(T(0) * U(0)) mul(T x, U y) {
   return x * y;
}

这对我来说看起来更清晰,而且它确实在将两个数字相乘时具有与第一个相同的效果......

mul(4, 3); // 12

那么为什么 Stroustrup 坚持使用复杂的指针、解引用和初始化语法呢?当然,这是在他引入新的 auto 语法之前。但是无论如何,我的问题是:以上两种形式的类型初始化有什么区别吗?他在哪里使用指针并立即取消引用它们,而不是简单地做我所做的,即在没有指针或取消引用的情况下初始化类型?任何回应表示赞赏。

最佳答案

您的版本是等效的。

  1. 您的版本假设TU 都可以从0 构造。从矩阵中期望这一点显然是错误的,但它们可以相乘。
  2. T(0) 产生一个临时的(可能绑定(bind)到 T&&)而 *(T*(0)) 产生一个引用现有对象(即 T&),因此可能会选择不同的运算符。

但是,Stroustrup 的版本和您的版本最终都没有被用于实践。在同等级别的编译器实现中,可以使用:

template <typename T, typename U>
decltype(std::declval<T>() * std::declval<U>()) mul(T x, U y);

但它未能利用延迟返回类型规范,该规范旨在允许在函数的参数声明之后推迟返回类型的声明:auto f (int, int) -> int。一旦声明了参数,就可以使用,这对 decltype 非常有用!

template <typename T, typename U>
auto mul(T x, U y) -> decltype(x * y);

后一种形式保证选择与函数体相同的运算符重载,但代价是重复(不幸的是)。

关于c++ - 将语法与匿名模板类型混淆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13322405/

相关文章:

C++ Windows MFC 并发 : Get thread to wait until particular state achieved

c++ - 使用正则表达式解析 CSS 表达式

c++ - VC++2013 中嵌套可变参数模板结构的别名

c++ - 如何测试 std::random_device 的随机性?

windows - Windows 上的线程创建速度慢

c++ - 如何通过结构体中的变量确定结构体是否存在于结构体​​ vector 中

c++ - Unix c++ : getline and line. 空不工作

c++ - 如何在 C++ 中返回结构数组?

c++ - SFINAE 类型集包含的类型

C++ 映射模板派生类