请查看此非编译代码段:
struct Object {
template <RETURN (OBJECT::*MEMFN)(PARAMETERS...), typename RETURN, typename OBJECT, typename ...PARAMETERS>
void call() {
}
};
struct Foo {
void fn();
};
int main() {
Object o;
o.call<&Foo::fn>();
}
基本上,我想要实现的是拥有一个函数(Object::call
),它专门用于任何类型的成员函数指针,并且具有方便的语法来调用。
我找到的最近的解决方案就是这个,这非常难看:
struct Object {
};
template <typename MEMFNTYPE, MEMFNTYPE MEMFN>
struct Caller;
template <typename RETURN, typename OBJECT, typename ...PARAMETERS, RETURN (OBJECT::*MEMFN)(PARAMETERS...)>
struct Caller<RETURN (OBJECT::*)(PARAMETERS...), MEMFN> {
Object *object;
Caller(Object &o) : object(&o) { }
void call() {
// I have the necessary information here: the member function pointer as template parameter, and a pointer to Object
}
};
struct Foo {
void fn();
};
int main() {
Object o;
Caller<decltype(&Foo::fn), &Foo::fn>(o).call();
}
这个问题有更好的解决方案吗?
(原因是我尝试这样做是因为我想为其他成员函数创建包装函数(call
))
Kerrek SB建议使用auto
,我试过这个:
struct Object {
template <auto MEMFN>
void call();
template <auto MEMFN, typename RETURN, typename OBJECT, typename ...PARAMETERS>
void call<RETURN (OBJECT::*MEMFN)(PARAMETERS...)>() {
}
};
struct Foo {
void fn();
};
int main() {
Object o;
o.call<&Foo::fn>();
}
但是,这不会编译(我是否需要以不同方式添加MEMFN
到模板参数列表(而不是auto MEMFN
?):
t2.cpp:6:7: error: parse error in template argument list
void call<RETURN (OBJECT::*MEMFN)(PARAMETERS...)>() {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t2.cpp:6:52: error: non-class, non-variable partial specialization ‘call<<expression error> >’ is not allowed
void call<RETURN (OBJECT::*MEMFN)(PARAMETERS...)>() {
答案 0 :(得分:2)
正如评论中所建议的,如果你接受C ++ 17解决方案,那么auto
就是你的朋友。 <type_traits>
和if constexpr
:
#include <type_traits>
#include <iostream>
struct Object {
template <auto MEMFN>
void call() {
if constexpr (std::is_member_function_pointer_v<decltype(MEMFN)>)
std::cout << "Is member\n";
}
};
struct Foo {
void fn();
};
int main() {
Object o;
o.call<&Foo::fn>();
}
如果类型特征确实是这样,函数体将只发出将参数视为成员函数指针的代码。不需要专业化。