将语法与匿名模板类型混淆
Confusing syntax with anonymous template types?
template <class T, class U> decltype(*(T*)(0) * *(U*)(0)) mul(T x, U y) {
return x * y;
}
该代码取自Stroustrup的C 11常见问题解答。我了解它的作用,这是乘以不同类型的两个对象。使我感到困惑的是模板参数与函数定义之间的语法。decltype
内发生了什么?我认为它正在取消初始化为0的未征用的T
指针,并将其乘以以相同方式删除和初始化的未命名的U
指针。我是吗?
好吧,如果这是发生了什么,那么使用指针,dereences和额外的括号不是多余的吗?我不能在保持所需效果的同时初始化这样的类型?:
template <class T, class U> decltype(T(0) * U(0)) mul(T x, U y) {
return x * y;
}
这对我来说看起来要干净很多,在乘以两个数字时具有相同的效果...
mul(4, 3); // 12
那么,为什么Stroustrup坚持使用复杂的指针,取消和初始化语法?当然,这是在他介绍新的auto
语法之前。但是无论如何,我的问题是:上述两种类型初始化形式之间是否有区别?他在哪里使用指针并立即使用它们,而不是简单地做我所做的事情,这是在没有指针或删除的情况下初始化类型的初始化?任何响应都将被赞赏。
您的版本是不是等效的。
- 您的版本认为
T
和U
都可以从0
构造。从矩阵中期待这一点显然是错误的,但是可以乘以它们。 -
T(0)
产生临时性(可能绑定到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);
保证后一种形式可以选择相同的运算符超载,而不是功能主体,以重复费用(不幸的是)。
您的代码版本假设t和u具有默认的构造函数。Stroustrup版本没有,它通过取消定位空指针来创建虚拟对象。当然,这并不重要,因为该代码并不是要执行的,它只是要解析以了解所得类型。
decltype
内容是未评估的上下文;只要与某种类型产生,那里的情况都没关系。考虑一下T
的定义:
struct T
{
int operator*(const U &) { return 2; }
};
它没有构造函数服用int
或int
可转换为的任何类型;因此,即使在decltype
的未评估上下文中,T(0)
也不会导致对象。因此,使用未评估的空引用可能是获得正确类型的最简单方法。
底线:您不知道T
和U
有哪些构造函数,因此您应该使用null引用,该引用适用类型的虚拟对象。
- 赋值到类型和空大括号. 语法说明
- 模板<>模板<类型名 T> 语法有什么用?
- 这是什么类型的C++语法,我应该采取什么步骤来理解这一点
- 截至 C++14 起尾随返回类型语法的合法使用
- 正确语法,用于统一初始化名称中带有空格的类型的临时,如unsigned int
- 使用 pybind11 绑定 typedef 类型的正确语法是什么?
- 使用函数类型语法声明成员函数
- 应用于类型别名声明的 [[maybe_unused]] 属性的语法
- 将任何类型的表达式放在 c++ 的初始化列表中在语法上是否正确?
- C 语法,根据此代码返回值类型
- 返回类型布尔函数中的声明语法错误
- 函数模板专用化语法聚合模板化类型
- 是否可以在尾随返回类型语法中直接使用参数值(不是其类型,而是值本身)
- 有人能解释一下特殊的std::函数模板参数列表语法(这个奇怪的类型(Types..))吗
- 嵌套模板类返回类型在 C++ 中的头文件中函数返回类型的语法
- GCC 中的编译器错误,但在将 decltype 与具有尾随返回类型语法的模板化成员函数一起使用时没有 clang
- 是否可以通过从lambda的引用中返回T型对象,而无需使用尾随返回类型语法
- typedef T类型::*语法
- 由于noexcept说明符,尾随返回类型语法失败
- Int (Int, Int)样式模板函数类型语法