我正在阅读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})
也应该有用。
答案 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))
仅在T
和U
让构造函数采用单个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&&
)