为什么result_of可以接受函函数类型为lvalue_reference,而不能接受函数类型为lvalue_refe



我有下面的程序:

#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)"是OK的

(1)我有一个类似的帖子在另一个线程c++ 11的结果推断我的函数类型失败。但是它并没有说明为什么函数函数对象可以,而函数对象不行。

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

(3)只要我知道,任何有名字的标记,比如变量/函数,都应该被认为是l值。在函数参数的情况下,编译器应该"衰减"我的函数名"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)只要我知道,任何有名字的标记,比如变量/函数,都应该被认为是l值。在函数参数的情况下,编译器应该"衰减"我的函数名"f"到一个函数指针,对吗?

不,见上文。你的call(F&)函数通过引用接受它的参数,所以没有衰减。

(4)这就像衰减一个数组并将其传递给一个函数----函数指针可以是一个l值,那么"call(F&f)"?

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

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

相关内容

  • 没有找到相关文章

最新更新