Function C++;11:为什么的结果_可以接受函子类型作为左值_引用,而不能接受函数类型作为左值_引用?

Function C++;11:为什么的结果_可以接受函子类型作为左值_引用,而不能接受函数类型作为左值_引用?,function,c++11,types,reference,result-of,Function,C++11,Types,Reference,Result Of,我有以下程序: #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(){ret

我有以下程序:

#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;
}
#包括
#包括
使用名称空间std;
模板
R调用(F&F){return F();}
结构{
双运算符(){return 0.0;}
};
int f(){return 1;}
int main()
{
S obj;
调用(obj);//好的
调用(f);//错误!
返回0;
}
它在“call(f)”行中编译失败。 奇怪的是,“呼叫(obj)”没问题

(1) 我在另一个帖子里也有类似的帖子。但它并没有说明为什么函子对象是正常的,而函数不是

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

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

(4) 这就像衰减一个数组并将其传递给一个函数——而函数指针可以是一个l值,那么“调用(F&F)”有什么错呢

你能帮我进一步解释一下“为什么”是我的情况吗?我哪里出错了?
谢谢。

调用(f)的问题是您将
f
推断为函数类型,因此它不会衰减为函数指针。相反,您会得到一个函数的引用。然后,< <代码>表达式的<代码>结果无效,因为<代码> f>(<代码)> <代码>()()>代码>,即返回一个函数,该函数不是C++中的有效类型(函数可以返回指针到函数,或者引用函数,但不是函数)。 如果您使用的
result\u,它将起作用,因为这是调用可调用对象的方式,因此更准确。在
call(F&F)
内部执行
F()
操作,在该上下文中
F
是一个左值,因此您应该询问在没有参数的情况下调用左值
F
的结果是什么,否则您可能会得到错误的答案。考虑:

struct S {
  double operator()()& {return 0.0;}
  void operator()()&& { }
};
现在,type
结果是
void
,这不是您想要的答案

如果使用
result\u,则会得到正确答案,而且当
F
是函数类型时,它也会起作用,因此
call(F)
也会起作用

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

不,见上文。您的
调用(F&)
函数通过引用获取其参数,因此没有衰减

(4) 这就像衰减一个数组并将其传递给一个函数——而函数指针可以是一个l值,那么“调用(F&F)”有什么错呢

数组在通过引用传递时也不会衰减


如果希望参数衰减,那么应该编写
call(F&F)
而不是
call(F&F)
。但是,即使这样做,您仍然需要正确地使用
result\u of
来获得
f()
的结果,其中
f
是一个左值。

可能与您不能说
template struct f{}的原因相同;F{}