我意识到“为什么事情就像他们一样”问题通常不是最好的问题,但是有很多人都在调整标准委员会的讨论,所以我希望这可以在事实上得到回答,因为我合法地好奇至于答案是什么。
基本上,我第一次看到它时花了很长时间才弄清楚std::result_of
的模板签名是怎么回事:我认为这是一个全新的模板参数构造,我从来没有之前见过。
template< class F, class... ArgTypes >
class result_of<F(ArgTypes...)>;
经过一段时间的思考后,我意识到这实际上是什么:F(ArgTypes...)
是一个函数类型,但它是不正在评估其结果类型的函数的类型(即只是F
):这是一个采用ArgTypes...
参数和返回类型F
的函数类型。
这不是......奇怪吗?有点hackish?有没有人知道委员会是否讨论过任何替代方案,例如,以下......
template< class F, class... ArgTypes >
class result_of<F, ArgTypes...>;
我想有可能存在第二种结构不能像第一种结构那样容易使用的情况,但是哪种情况呢?
我不是试图对此作出判断,但只是在我第一次看到它时这对我来说是合法的混淆,所以我很好奇是否有充分的理由。我意识到部分答案可能只是“因为Boost这样做了”,但仍留下剩下的(事实)问题...
是否存在技术原因Boost选择此语法来编码类型信息而不是任何替代方法?
C ++ 11委员会是否有任何关于标准化这一点的适当性的讨论,因为std::result_of
可以相当容易地以decltype
方式实现?
答案 0 :(得分:17)
使用函数类型作为参数,即使在C ++ 03中也可以使用不受限制的“可变参数”类模板。想一想:在C ++ 03中,我们没有可变参数模板。并且你不能像使用函数模板那样“重载”类模板 - 那么如何在函数中允许不同数量的“参数”呢?
使用函数类型,您只需为不同数量的参数添加任意数量的部分特化:
template<class Fty>
struct result_of;
template<class F>
struct result_of<F()>{ /*...*/ };
template<class F, class A0>
struct result_of<F(A0)>{ /*...*/ };
template<class F, class A0, class A1>
struct result_of<F(A0, A1)>{ /*...*/ };
// ...
在C ++ 03中执行此操作的唯一其他方法是默认模板参数,并且对于每种情况都部分特殊 - 缺点是它看起来不再像函数调用,并且任何类型的包装器都使用{ {1}}内部不能只传递result_of
。
现在,功能类型方式有一个缺点 - 您还可以完成对“参数”的所有常规转换:Sig
- &gt; R(Args...)
,更重要的是R(*)(Args...)
- &gt; T[N]
和顶级cv限定符被丢弃(T*
):
§8.3.5/5
错误:静态断言失败:/ cry
其他问题是顶级cv限定符被丢弃:
struct X{
bool operator()(int (&&arr)[3]);
long operator()(void*);
};
static_assert(std::is_same<std::result_of<X(int[3])>::type, bool>(), "/cry");
错误:静态断言失败:/ cry
答案 1 :(得分:9)
我认为只是有人认为你可以(ab)使用函数类型表示法来模仿各个函子调用的样子,并且它会卡住。所以,没有技术原因,只是美学原因。
// the result type of a call to (an object of) type F,
// passing (objects of) types A, B, and C as parameters.
result_of<F(A, B, C)>::type
答案 2 :(得分:4)
result_of
是TR1的一部分,它在将decltype添加到语言之前出现。但它的设计考虑了decltype
,因此将result_of
的实现更改为使用decltype
很简单。是的,这是一个黑客,但它的确有效。
答案 3 :(得分:2)
(这会扩展到JohannesD's answer和Jesse Good's comment,但这不适用于评论。请注意其他答案不是这个。)
result_of
行为的定义很简单:给定类型F
,T1
,T2
,...,TN
和左值{{这些类型分别为1}},f
,t1
,...,t2
,类型表达式
tN
计算表达式
result_of<F(T1, T2, ..., TN)>::type
的类型。
这不是滥用类型系统,它非常优雅!