0

我确实对std::result_of<>.

因此,如果我理解正确,R (Args..)编译器应该将表单解释为采用类型参数Args...和返回类型的函数类型R,并且在指定时使用非常合理std::function<int(int)>,它声明了一个函数类型int作为其唯一参数,并返回int

但是,当在上下文中使用相同的概念时,上面的含义突然发生了变化std::result_of<F(Args...)>(注意,我更改RF,并删除了 and之间的(空格)以表示差异-根据 cppreference, 的含义变成了编译时间表达式 - 我的意思是,我有点理解 的主要目的是使用 的概念来选择正确的重载(如果存在多个重载),当然还可以推断出这种调用的返回类型(在编译时解析期间) - 实际上,这大致类似于:- 但是,- 与F(F(Args...)INVOKEstd::result_of<F(Args...)>INVOKEdecltype(std::declval<F>()(std::declval<Args>()...))F (Args...)std::function<R (Args...)>case - 编译器会解释为一个函数类型,接受Args...并返回类型F,现在F是我们试图获取返回类型的函数类型!

当然,在 and 的帮助下decltypestd::declval实现std::result_of似乎是合理的,但是我读到了result_of在 C++98/03 中以某种方式实现的 boostdecltype并且std::declval不存在 - 我想知道这怎么可能(也许有一些非常 hack '小把戏)?

所以重新迭代:R (Args...)在作为模板参数的上下文中的概念是否总是被解释/推断为具有返回类型的函数类型R,无论封闭模板是std::function<>还是std::result_of<>?虽然std::result_of<>以某种方式对“返回类型”进行了某种重新解释F,并“返回”了定义的实际返回类型std::result_of<F(Args...)>::type?或者std::result_of<F(Args...)>只是解释F(Args...)不同,所以它知道这是一个神奇的INVOKE表达?

感谢您即将进行的澄清!

4

2 回答 2

3

Z(A,B,C)只是一种类型。它是一个函数类型。

您可以将类型传递给模板。模板对类型的作用取决于模板。

std::function<X>需要一个函数类型。它将它转换成它的签名operator()

std::result_of<X>需要一个函数类型。如果给定A(Ts...),它会计算使用参数()调用类型对象的结果。ATs...

中被标记为 deprecated,因为函数类型有时会做一些有趣的事情(衰减参数、strip const 等)。现在invoke_result<F, Ts...>,它的行为result_of<F(Ts...)>与一些极端情况差异非常相似。

结果总是滥用函数类型语法。但这里没有深奥的魔法;模板对传入的类型做任何他们想做的事情。

中,您可以通过模式匹配函数指针类型和检查&T::operator(). 如果没有 decltype/declval、编译器扩展或 TR pre- 头文件,就无法在中获得所需的全部功能。

于 2018-06-13T05:30:25.017 回答
1

要在没有的情况下实现它decltype——好吧,一个涵盖很少基本案例的简单的 carcass oldschool 实现可能类似于

template<class F> struct MemberRetVal;
template<class C,typename R> struct MemberRetVal<R (C::*)()> {
    using type = R;
};
template<class C,typename R> struct MemberRetVal<R (C::*)() const> {
    using type = R;
};
template<class C,typename R, typename A1> struct MemberRetVal<R (C::*)(A1)> {
    using type = R;
};
template<class C,typename R, typename A1> struct MemberRetVal<R (C::*)(A1) const> {
    using type = R;
};
// ...
// A few more member function arities
// ...

template<typename F> struct ResultOf;
template<typename F> struct ResultOf<F (*)()> {
    using type = typename MemberRetVal<&F::operator()>::type;
};
template<typename R> struct ResultOf<(R (*)())(*)()> {
    using type = R;
};
template<typename F, typename A1> struct ResultOf<F (*)(A1)> {
    using type = typename MemberRetVal<&F::operator()>::type;
};
template<typename R, typename A1> struct ResultOf<(R (*)(A1))(*)(A1)> {
    using type = R;
};
// and so forth

case需要更复杂的调度operator(),但除此之外——这是大致的方法。

于 2018-06-13T06:07:45.863 回答