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

标签 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(){return 1;}
int main()
{
    S obj;
    call(obj);//ok
    call(f);//error!
    return 0;
}

它无法在“call(f)”行中编译。
奇怪的是“call(obj)”是可以的。

(1) 我在另一个帖子 C++11 result_of deducing my function type failed 中有一个类似的帖子.但它并没有说明为什么仿函数对象可以,而函数则不行。

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

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

(4) 这就像衰减一个数组并将其传递给一个函数----而函数指针可能是一个l值,那么“call(F& f)”有什么问题?

您能否帮助进一步解释“为什么”是我的情况,我哪里出错了?
谢谢。

最佳答案

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) As long as I know, any token with a name, like variable/function, should be considered a l-value. And in the case of function parameter, compiler should "decay" my function name "f" to a function pointer, right?



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

(4) This is like decaying an array and pass it to a function----And a function pointer could be an l-value, then what's wrong with "call(F& f)"?



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

如果你想让参数衰减,那么你应该写 call(F f)不是 call(F& f) .但即使你这样做,你仍然需要使用 result_of正确获得 f() 的结果哪里f是一个左值。

关于function - C++11:为什么 result_of 可以接受仿函数类型作为 lvalue_reference,但不能接受函数类型作为 lvalue_reference?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38118563/

相关文章:

JavaScript 检查变量是否存在(已定义/初始化)

c++ - 为什么未使用的部分特化没有错误?

c++ - 自动检测基类的类型参数

scala - 试图找到更简单的方法来从特征中引用子类的类型

c - 为什么我们使用显式数据类型? (从低层次的角度来看)

php - 如何在 array_map 的可调用对象中实现类方法

C 最佳函数,用于在小于、等于和大于某个值的元素上分割数组

c - C中这两个程序有什么区别

c++ - 错误 : No matching function for call to class object

c++ - 将非常大的 int 转换为 double,某些计算机上的精度损失