繁体   English   中英

为什么Ampersand需要引用呼叫运营商

[英]Why Is Ampersand Necessary For Referencing The Call Operator

我认为C ++规范说在引用函数时不需要函数前面的符号,即

void bar();
void foo(void(*bar)());

foo(bar);
foo(&bar);  // Same as above.

但是,我发现了一个并非如此的情况。 我试图对lambda(仅一个参数)进行模板特化,这样我就可以访问lambda的return参数和输入参数的类型。

// The ampersand in front of 'Fn::operator()' is necessary to make
// this code work.
template <typename Lambda>
struct Signature : public Signature<decltype(&Fn::operator())> {};

template <typename ClassT, typename RetT, typename ArgT>
struct Signature<RetT(ClassT::*)(ArgT) const> {
  using ReturnType = RetT;
  using ArgumentType = ArgT;
};

没有&符号,clang抱怨道

error: call to non-static member function without an object argument
struct Signature : public Signature<decltype(Fn::operator())> {};
                                             ~~~~^~~~~~~~

我得到了代码,但我想了解它的工作原理。 为什么这里的&符必要?

要获取成员函数的地址,必须始终使用& (和号)作为前缀。 这不仅适用于模板和/或lambdas,而且适用于C ++中的任何成员函数。

至于为什么 ,我们只能推测。 但这就是C ++一直以来的方式。 也许C兼容性是允许省略& for for free功能的唯一原因。

函数的指针和成员函数的指针是不同的野兽。 当函数衰减到指向函数的指针时,对于成员函数或成员对象也是如此。 虽然指针转换有一个标准函数,但成员函数或成员对象没有类似的东西。 当你想获得一个指向成员的指针时,你总是需要使用&

我不知道确切的推理,但我怀疑运营商的地址是必要的,以避免有时出现功能的错误,例如:

int f();
// ...
if (f) { // always true
}

虽然在不破坏C兼容性的情况下无法删除从函数到函数指针的隐式转换,但在引入成员和成员指针时没有类似的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM