生成可以区分 ID(Foo::a()) 和 ID(Foo::b()) 的唯一标识符
Generate Unique Identifier that can distinguish ID(Foo::a()) from ID(Foo::b())
假设我有:
struct S{
void f(int);
float g(int,int);
void h(int);
}
#define UID(w) /* how to do it? */
cout << UID(S::f);
cout << UID(S::g);
cout << UID(S::h);
我需要一些方法来为每个成员创建唯一的编号、字符串或地址。
这是因为我将要使用:
#define BIND(foo) Generate<decltype(&foo), &foo>::call
u = & BIND(S::f)
v = & BIND(S::g)
w = & BIND(S::h)
即BIND
生成关联的 C 风格函数
这是生成器的草图:
template< typename F f >
struct Generate {}
template < typename R, typename ...Arg, R(S::*target)(Arg...) >
struct Generate< R(S::*)(Arg...),target >
{
static R call( PyObject* self, Arg... carg)
{
cout << ??? // the name, e.g. 'S::b'
我需要此函数 cout
生成它的 S::foo
的名称。
所以问题的后半部分是:如何从 call
中恢复相同的 UID?
我尝试创建 UID 的原因是我可以:
static std::map<void*, std::string> names_map;
然后我可以修改我的:
#define BIND(foo) Generate<decltype(&foo), &foo>::call; \
names_map[ UID(foo) ] = std::string(#foo);
static R call( PyObject* self, Arg... carg)
{
cout << names_map[ UID( R(S::*target)(Arg...) ) ];
但实际上如何做到这一点?
我整理了一个测试用例 on coliru -- 任何人都可以让它工作吗?
这听起来像是一个 XY 问题。您实际需要的是一种将特定类型 (Generate<...>
) 与可用作地图键的内容相关联的方法。有一种标准方法可以做到这一点 - 它被称为 std::type_index
.
static std::map<std::type_index, std::string> names_map;
/* ... */
template <typename R, typename... Arg, R(Base::*target)(Arg...)>
struct Generate< R(Base::*)(Arg...), target >
{
static void call()
{
std::cout << "TARG:" << names_map[ std::type_index( typeid(Generate) ) ] << std::endl;
}
};
#define BIND(fp, cxx_target) \
fp = &Generate< decltype(&cxx_target), &cxx_target >::call; \
names_map[ std::type_index(typeid(Generate< decltype(&cxx_target), &cxx_target >)) ] = std::string(#cxx_target);
Demo.
假设我有:
struct S{
void f(int);
float g(int,int);
void h(int);
}
#define UID(w) /* how to do it? */
cout << UID(S::f);
cout << UID(S::g);
cout << UID(S::h);
我需要一些方法来为每个成员创建唯一的编号、字符串或地址。
这是因为我将要使用:
#define BIND(foo) Generate<decltype(&foo), &foo>::call
u = & BIND(S::f)
v = & BIND(S::g)
w = & BIND(S::h)
即BIND
生成关联的 C 风格函数
这是生成器的草图:
template< typename F f >
struct Generate {}
template < typename R, typename ...Arg, R(S::*target)(Arg...) >
struct Generate< R(S::*)(Arg...),target >
{
static R call( PyObject* self, Arg... carg)
{
cout << ??? // the name, e.g. 'S::b'
我需要此函数 cout
生成它的 S::foo
的名称。
所以问题的后半部分是:如何从 call
中恢复相同的 UID?
我尝试创建 UID 的原因是我可以:
static std::map<void*, std::string> names_map;
然后我可以修改我的:
#define BIND(foo) Generate<decltype(&foo), &foo>::call; \
names_map[ UID(foo) ] = std::string(#foo);
static R call( PyObject* self, Arg... carg)
{
cout << names_map[ UID( R(S::*target)(Arg...) ) ];
但实际上如何做到这一点?
我整理了一个测试用例 on coliru -- 任何人都可以让它工作吗?
这听起来像是一个 XY 问题。您实际需要的是一种将特定类型 (Generate<...>
) 与可用作地图键的内容相关联的方法。有一种标准方法可以做到这一点 - 它被称为 std::type_index
.
static std::map<std::type_index, std::string> names_map;
/* ... */
template <typename R, typename... Arg, R(Base::*target)(Arg...)>
struct Generate< R(Base::*)(Arg...), target >
{
static void call()
{
std::cout << "TARG:" << names_map[ std::type_index( typeid(Generate) ) ] << std::endl;
}
};
#define BIND(fp, cxx_target) \
fp = &Generate< decltype(&cxx_target), &cxx_target >::call; \
names_map[ std::type_index(typeid(Generate< decltype(&cxx_target), &cxx_target >)) ] = std::string(#cxx_target);
Demo.