gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 00:55:28 25 4
gpt4 key购买 nike

我有下面的程序:

#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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com