【发布时间】:2015-12-21 17:23:57
【问题描述】:
我认为 C++ 规范说,在引用函数时,函数前面的 & 符号是不必要的,即
void bar();
void foo(void(*bar)());
foo(bar);
foo(&bar); // Same as above.
但是,我发现了一个不正确的案例。我试图对 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;
};
没有和号,clang 抱怨
error: call to non-static member function without an object argument
struct Signature : public Signature<decltype(Fn::operator())> {};
~~~~^~~~~~~~
我让代码工作,但我想了解它为什么工作。为什么这里需要 & 符号?
【问题讨论】:
-
简单的答案是成员函数不是常规函数。也许 Bjarne 认为函数和函数指针的奇怪细节(例如,当你调用一个函数名称时衰减为指针)是一个错误,并且使成员函数及其指针的行为有所不同。不过,我不知道这种行为不同的真正原因。
-
成员函数释放函数的规则不同。指向成员的指针与普通函数指针不同
-
请注意,您的模板魔法不会在任何地方都起作用(我在想例如使用
const类的地方。最好使用std类型的特征,如std::result_of. -
@Rubenvb,感谢您建议
std::result_of。有没有类似的获取参数类型的方法? -
@kirakun 我相信你需要 Boost:boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/…