【问题标题】:What does this syntax " decltype(*(T*)(0)**(U*)(0)) " mean?这个语法“ decltype(*(T*)(0)**(U*)(0)) ”是什么意思?
【发布时间】:2015-12-04 09:35:09
【问题描述】:

我在看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) -&gt; 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}) 也应该可以。

【问题讨论】:

  • 假设TU 有一个构造函数,它接受一个整数参数。指针方式不对TU的构造函数做任何假设。
  • 注意,它不是未定义的行为,因为它是in an unevaluated context

标签: c++ c++11


【解决方案1】:

这确实容易出错。

在您的解决方案中,您基本上假设构造函数可以将0 作为参数,但事实可能并非如此。

sn-p 基本上将NULL 转换为某个T 对象指针,然后使用* 运算符拉出T,现在我们基本上留下decltype({T object}*{U object}),它假定在编译时,@ 987654327@ 将被实际类型替换,并且在运行时将没有指针。但是这段代码非常丑陋且不可维护。

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

declval 做了类似于*(T*)(0) 的事情,只是它返回右值引用(意思是T&amp;&amp;

【讨论】:

  • 这不是result_of 的用途,它不会在这里编译。
【解决方案2】:
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>())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 2015-03-20
    • 1970-01-01
    • 2018-09-10
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多