生成可以区分ID(Foo :: a())和ID(Foo :: b())的唯一标识符 [英] Generate Unique Identifier that can distinguish ID(Foo::a()) from ID(Foo::b())

查看:278
本文介绍了生成可以区分ID(Foo :: a())和ID(Foo :: b())的唯一标识符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有:

  struct S {
void f
float g(int,int);
void h(int);
}

#define UID(w)/ *怎么办? * /

cout<< UID(S :: f);
cout< UID(S :: g);
cout< UID(S :: h);

我需要某种方法为每个成员创建一个唯一的数字,字符串或地址。

这是因为我要使用:

  #define BIND foo)生成< decltype(& foo),& foo> :: call 

u =& BIND(S :: f)
v =& BIND(S :: g)
w =& BIND(S :: h)

BIND 生成关联的C风格函数



这是生成器的草图:

 模板<类型名F f> 
struct Generate {}

template<类型名称R,类型名称... Arg,R(S :: * target)(Arg ...)
struct Generate< R(S :: *)(Arg ...),target>
{
static R call(PyObject * self,Arg ... carg)
{
cout< ??? //名称,例如'S :: b'

我需要这个函数 cout 生成它的 S :: foo 的名称。



问题是:如何从调用中恢复相同的UID?



我尝试创建UID的原因是,我可以创建:

  static std :: map< void *,std :: string> names_map; 

然后我可以修改我的:

  #define BIND(foo)生成< 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 ...))];

但是如何实际操作呢?



我在 coliru 上放置了一个测试用例,任何人都可以使用它吗? / p>

解决方案

这听起来像是一个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);

演示


Say I have:

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);

I need some way of creating a unique number, string or address for each member.

This is because I'm going to be using:

#define BIND(foo) Generate<decltype(&foo), &foo>::call

u = & BIND(S::f)
v = & BIND(S::g)
w = & BIND(S::h)

i.e. BIND generates an associated C-style function

Here is a sketch of the generator:

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'

I need this function to cout the name of the S::foo that generated it.

So the second half of the question is: how can I recover the same UID from inside call?

The reason I'm trying to create UIDs is so that I can make a:

static std::map<void*, std::string> names_map;

Then I can modify my:

#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...)  ) ];

But how to actually do this?

I've put together a testcase on coliru -- can anyone make it work?

解决方案

This sounds like an XY problem. What you actually need is a way to associate a particular type (Generate<...>) to something that can be used as a key in a map. There is a standard way to do that - it's called 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.

这篇关于生成可以区分ID(Foo :: a())和ID(Foo :: b())的唯一标识符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆