这个语法是什么" decltype(*(T *)(0)**(U *)(0))"意思?

时间:2015-09-08 15:53:50

标签: c++ c++11

我正在阅读this question on isocpp FAQ here,此问题解释了如何为???

编写返回类型
template<class T, class U>
??? mul(T x, U y)
{
return x*y;
}

我理解简单的方法是撰写auto mul(T x, U y) -> decltype(x*y),但问题还提供了另一种方法,即用???替换decltype(*(T*)(0)**(U*)(0))。但是我不完全理解这个decltype(*(T*)(0)**(U*)(0))到底在做什么,似乎它正在声明一个临时指针T*并将其初始化为零然后取消引用指针,然后再乘以它类型U的对应物,我的理解是对吗?

但为什么要使用指针?我认为decltype(T(0)*U(0))decltype(T{0}*U{0})也应该有用。

2 个答案:

答案 0 :(得分:21)

decltype(*(T*)(0)**(U*)(0))

让我们把它分开:

(T*)(0) //cast a null pointer to a T*
*(T*)(0) //dereference, giving a T

(U*)(0) //cast a null pointer to a U*
*(U*)(0) //dereference, giving a U

(*(T*)(0)) * (*(U*)(0)) //the result of multiplying a U and a T

decltype(T(0)*U(0))仅在TU让构造函数采用单个int(或者可以隐式转换为整数文字的内容)时才是等效的。

标准库已经有std::declval以更干净的方式执行此操作:

decltype(std::declval<T>() * std::declval<U>())

答案 1 :(得分:0)

这确实容易出错。

在您的解决方案中,您基本上假设construcor可以获得0作为参数,而情况可能并非如此。

该代码段基本上将NULL投射到某个T对象指针,然后使用T运算符拉出*,现在我们基本上decltype({T object}*{U object})了假设在编译时,decltype将被实际类型替换,并且在运行时将没有指针。但是这段代码非常丑陋且无法维护。

更好的解决方案是使用C ++ 11 std::result_of
typename std::result_of<declval<T>()*declval<U>()>::type

declval执行与*(T*)(0)类似的操作,只返回 r-value reference (意为T&&