简体   繁体   English

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

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

I thought the C++ specification says an ampersand in front of a function is not necessary when referencing a function, ie 我认为C ++规范说在引用函数时不需要函数前面的符号,即

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

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

However, I found a case where this is not true. 但是,我发现了一个并非如此的情况。 I was trying to do template specialization over lambda (of a single argument only) so that I could access the types of both the return argument and the input argument of a lambda. 我试图对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;
};

Without the ampersand, clang complains 没有&符号,clang抱怨道

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

I got the code to work, but I would like to understand why it works. 我得到了代码,但我想了解它的工作原理。 Why is the ampersand necessary here? 为什么这里的&符必要?

To take the address of a member function, you must always prefix it with & (ampersand). 要获取成员函数的地址,必须始终使用& (和号)作为前缀。 This is true not only for templates and/or lambdas, but any member function in C++. 这不仅适用于模板和/或lambdas,而且适用于C ++中的任何成员函数。

As for why , we can only speculate. 至于为什么 ,我们只能推测。 But this is how C++ has always been. 但这就是C ++一直以来的方式。 Perhaps C compatibility is the only reason omitting the & for free functions is allowed. 也许C兼容性是允许省略& for for free功能的唯一原因。

Pointers to functions and pointers to member functions are different beasts. 函数的指针和成员函数的指针是不同的野兽。 While functions decay to pointers to functions, the same is not true for member functions or member objects. 当函数衰减到指向函数的指针时,对于成员函数或成员对象也是如此。 While there is a standard function to pointer conversion there is nothing similar for member functions or member objects. 虽然指针转换有一个标准函数,但成员函数或成员对象没有类似的东西。 When you want to get a pointer to member you always need to use an & . 当你想获得一个指向成员的指针时,你总是需要使用&

I don't know the exact reasoning but I suspect that the address-of operator was required to avoid mistakes which sometimes show up with functions, eg: 我不知道确切的推理,但我怀疑运营商的地址是必要的,以避免有时出现功能的错误,例如:

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

While the implicit conversion from functions to function pointers couldn't be removed without breaking C compatibility, there was no similar concern when members and pointer to members were introduced. 虽然在不破坏C兼容性的情况下无法删除从函数到函数指针的隐式转换,但在引入成员和成员指针时没有类似的问题。

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

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