为什么引用呼叫接线员时必须使用符号AND 我认为C++规范在引用函数时不需要在函数前面加一个符号,即 void bar(); void foo(void(*bar)()); foo(bar); foo(&bar); // Same as above.

为什么引用呼叫接线员时必须使用符号AND 我认为C++规范在引用函数时不需要在函数前面加一个符号,即 void bar(); void foo(void(*bar)()); foo(bar); foo(&bar); // Same as above.,c++,templates,C++,Templates,然而,我发现了一个情况,这是不正确的。我试图对lambda(仅一个参数)进行模板专门化,以便能够访问lambda的返回参数和输入参数的类型 // The ampersand in front of 'Fn::operator()' is necessary to make // this code work. template <typename Lambda> struct Signature : public Signature<decltype(&Fn::oper

然而,我发现了一个情况,这是不正确的。我试图对lambda(仅一个参数)进行模板专门化,以便能够访问lambda的返回参数和输入参数的类型

// 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;
};
//必须在'Fn::operator()'前面加上符号才能使
//这段代码有效。
模板
结构签名:公共签名{};
模板
结构签名{
使用ReturnType=RetT;
使用ArgumentType=ArgT;
};
没有符号,叮当抱怨

error: call to non-static member function without an object argument
struct Signature : public Signature<decltype(Fn::operator())> {};
                                             ~~~~^~~~~~~~
错误:在没有对象参数的情况下调用非静态成员函数
结构签名:公共签名{};
~~~~^~~~~~~~

我让代码工作,但我想了解它为什么工作。为什么这里必须使用符号AND?

要获取成员函数的地址,必须始终在其前面加上
&
(符号AND)。这不仅对模板和/或lambdas是正确的,而且C++中的任何成员函数都是正确的。
至于原因,我们只能猜测。但这就是C++一直以来的方式。也许C兼容性是允许对自由函数省略
&
的唯一原因。

指向函数的指针和指向成员函数的指针是不同的。虽然函数衰减为指向函数的指针,但对于成员函数或成员对象,情况并非如此。虽然有一个标准的函数到指针的转换,但成员函数或成员对象没有类似的转换。当您想要获取指向成员的指针时,始终需要使用
&

我不知道确切的原因,但我怀疑操作员的地址是为了避免有时出现在函数中的错误,例如:

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

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

简单的答案是成员函数不是常规函数。也许Bjarne认为函数和函数指针的奇怪细节(例如,函数名在调用指针时衰减为指针)是一个错误,并使成员函数及其指针的行为不同。不过,我不知道这种行为不同的真正原因。成员函数有不同的释放函数的规则。指向成员的指针与普通函数指针是不同的。请注意,模板魔法不会在任何地方都起作用(我在想,例如,在哪里使用了
const
类。你最好使用
std
类型特征,比如@Rubenvb,谢谢你建议
std::result\u of
。有没有类似的方法来获取参数类型?@kirakun我相信你需要提高一下: