C ++ 11:为什么result_of可以接受函子类型作为lvalue_reference,但不能接受函数类型作为lvalue_reference?

Troskyvs

我下面有程序:

#include<type_traits>
#include<iostream>
using namespace std;
template <class F, class R = typename result_of<F()>::type>
R call(F& f) { return f(); }

struct S {
    double operator()(){return 0.0;}
};
int f(){return 1;}
int main()
{
    S obj;
    call(obj);//ok
    call(f);//error!
    return 0;
}

无法在“ call(f)”行中进行编译。“ call(obj)”还可以,这很奇怪。

(1)我在另一个线程C ++ 11 result_of中有一个类似的帖子,推论出我的函数类型failed但这并不能说明为什么函子对象没问题,而函数却没问题。

(2)我不确定这是否与“ R call(F&f)”有关:函数类型不能声明l值吗?

(3)据我所知,任何带有名称的令牌(如变量/函数)都应视为l值。对于函数参数,编译器应将我的函数名称“ f”“衰减”到函数指针,对吗?

(4)这就像衰减数组并将其传递给函数一样-函数指针可能是一个l值,那么“ call(F&f)”又是怎么回事呢?

您是否可以对“为什么”是我的情况做进一步的解释,我哪里弄错了?谢谢。

乔纳森·韦克利(Jonathan Wakely)

问题call(f)在于您可以推断F为函数类型,因此它不会衰减为函数指针。相反,您获得了对函数的引用。result_of<F()>表达式是无效的,因为F()就是int()()即一个函数,它返回一个函数,这是不是在C的有效类型++(函数可以返回函数指针,或引用功能,但不能函数)。

如果您使用result_of<F&()>更准确的方法,它将起作用,因为这就是调用可调用对象的方式。在内部call(F& f)执行此操作,f()并且在这种情况下f是一个左值,因此您应该问一下F不带参数的左值调用的结果是什么,否则您可能会得到错误的答案。考虑:

struct S {
  double operator()()& {return 0.0;}
  void operator()()&& { }
};

现在result_of<F()>::typevoid,这不是您想要的答案。

如果使用,result_of<F&()>则将得到正确的答案,并且当F是函数类型时也可以使用,因此call(f)也可以使用。

(3)据我所知,任何带有名称的令牌(如变量/函数)都应视为l值。对于函数参数,编译器应将我的函数名称“ f”“衰减”到函数指针,对吗?

不,请参见上面。您的call(F&)函数通过引用来接受其参数,因此不会衰减。

(4)这就像衰减数组并将其传递给函数一样-函数指针可能是一个l值,那么“ call(F&f)”又是怎么回事呢?

当您通过引用传递数组时,它们也不会衰减。

如果你想在参数衰减,那么你应该写的call(F f)不是call(F& f)但是,即使这样做,您仍然需要result_of正确使用以得到f()wheref是左值的结果

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档