将成员函数指针作为模板类型传递
Passing member function pointer as a template type
我不明白为什么clang拒绝这段代码。我从我的朋友那里得到它,并在VisualStudio上为他编译…我有TOT of clang.
#include <utility>
#include <iostream>
template< typename Signature >
class Delegate;
template< typename Ret, typename Param >
class Delegate< Ret(Param) >
{
public:
Ret operator()(Param&& p_param)
{
return m_ifunc(m_obj, std::forward< Param >(p_param));
}
template< typename ObjType, typename Ret(ObjType::*Method)(Param) >
friend auto createDelegate(ObjType * const p_obj)
{
Delegate< Ret(Param) > del;
del.m_obj = p_obj;
del.m_ifunc = &ifunction< ObjType, Method >;
return del;
}
private:
void * const m_obj = nullptr;
Ret (*m_ifunc)(void*, Param&&) = nullptr;
template< typename ObjType, typename Ret(ObjType::*Method)(Param) >
static Ret ifunction(void * const p_obj, Param&& p_param)
{
ObjType * const obj = (ObjType * const) p_obj;
return (obj->*Method)(std::forward< Param >(p_param));
}
};
struct Test
{
void test(int x)
{
std::cout << x << std::endl;
}
};
int main()
{
Test t;
Delegate< void(int) > d = Delegate< void(int) >::createDelegate< Test, &Test::test >(&t);
d(5);
}
这是我得到的错误有人明白是怎么回事吗?我看到过这种为函数指针指定模板参数的方式,我猜这对clang的严格性有一定的影响。
main.cpp:17:41: error: expected a qualified name after 'typename'
template< typename ObjType, typename Ret(ObjType::*Method)(Param) >
^
main.cpp:31:41: error: expected a qualified name after 'typename'
template< typename ObjType, typename Ret(ObjType::*Method)(Param) >
^
main.cpp:52:53: error: no member named 'createDelegate' in 'Delegate<void (int)>'
Delegate< void(int) > d = Delegate< void(int) >::createDelegate< Test, &Test::test >(&t);
~~~~~~~~~~~~~~~~~~~~~~~^
main.cpp:52:69: error: 'Test' does not refer to a value
Delegate< void(int) > d = Delegate< void(int) >::createDelegate< Test, &Test::test >(&t);
^
main.cpp:39:8: note: declared here
struct Test
^
main.cpp:52:82: error: definition or redeclaration of 'test' not allowed inside a function
Delegate< void(int) > d = Delegate< void(int) >::createDelegate< Test, &Test::test >(&t);
~~~~~~^
main.cpp:52:86: error: expected ';' at end of declaration
Delegate< void(int) > d = Delegate< void(int) >::createDelegate< Test, &Test::test >(&t);
^
你的代码有几个问题,我很确定它从来没有在VisualStudio上以目前的形式编译。在任何情况下,我不能得到它在VS2013上编译。下面是错误:
template< typename ObjType, typename Ret(ObjType::*Method)(Param) >
// ^^^^^^^^
// the member function pointer is a non-type template parameter, remove typename
friend auto createDelegate(ObjType * const p_obj)
// ^^^^
// you've declared this as a friend, but call it within main() as if it is a
// static member function, change 'friend' to 'static'
template< typename ObjType, typename Ret(ObjType::*Method)(Param) >
// ^^^^^^^^
// same as above, remove typename
static Ret ifunction(void * const p_obj, Param&& p_param)
m_obj
数据成员是一个const
指针,但是你试图将它指向createDelegate
void * const m_obj = nullptr;
// ^^^^^
// remove the const
完成这些修改后
template< typename Signature >
class Delegate;
template< typename Ret, typename Param >
class Delegate< Ret(Param) >
{
public:
Ret operator()(Param&& p_param)
{
return m_ifunc(m_obj, std::forward< Param >(p_param));
}
template< typename ObjType, Ret(ObjType::*Method)(Param) >
static auto createDelegate(ObjType * const p_obj)
{
Delegate< Ret(Param) > del;
del.m_obj = p_obj;
del.m_ifunc = &ifunction< ObjType, Method >;
return del;
}
private:
void * m_obj = nullptr;
Ret (*m_ifunc)(void*, Param&&) = nullptr;
template< typename ObjType, Ret(ObjType::*Method)(Param) >
static Ret ifunction(void * const p_obj, Param&& p_param)
{
ObjType * const obj = (ObjType * const) p_obj;
return (obj->*Method)(std::forward< Param >(p_param));
}
};
现在代码编译,输出5
。现场演示
要在VS2013(发布版本,不知道CTP)上编译,需要进行额外的更改。由于VS2013没有实现c++ 14对普通函数的返回类型推导,因此createDelegate
需要显式指定返回类型
template< typename ObjType, Ret(ObjType::*Method)(Param) >
static Delegate< Ret(Param) > createDelegate(ObjType * const p_obj)
{ /* ... */ }
最后,为了确保您了解其他选项:
Test t;
auto d = std::bind(&Test::test, t, std::placeholders::_1);
d(5); // prints 5
std::function<void(int)> d2 = std::bind(&Test::test, t, std::placeholders::_1);
d2(5); // prints 5
相关文章:
- 访问C++中的类型成员
- 具有 STL 向量类型成员的类的复制内存
- 重载具有 2 个相同数据类型成员的构造函数
- std::void_t 和嵌套的非类型成员
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 使用各种数据类型成员创建对象的简便方法
- 将类类型成员定义为公共和私有之间有什么区别?
- 结构类型成员的默认构造函数中的默认参数
- 如何传递模板模板非类型成员函数指针
- 文本类类型成员函数约束
- 给定仅包含布尔类型成员的结构的两个对象 s1 和 s2,只要 s1 的成员为 true,请检查 s2 的每个成员是否为真
- 如何在 c++ 中使用二进制文件输入/输出读取/写入结构的字符串类型成员
- C++:将模板参数的模板类型成员加为好友的语法正确吗
- C++静态结构类型成员初始化
- C++:作为引用或指针的基类型成员变量
- 左值引用类型成员的用户定义移动构造函数
- 具有指针类型成员的类在 MSVS2012@debug 下销毁时失败.程序错误或错误源
- CRTP -- 访问不完整的类型成员
- 为什么C++默认初始化不对非类类型成员进行零初始化
- 请求非类类型成员