如何在编译时将指针保存到成员? [英] How to save pointer to member in compile time?

查看:73
本文介绍了如何在编译时将指针保存到成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码

  template< typename T,int N& 
struct A {
typedef T value_type; // 好。保存T到value_type
static const int size = N; // 好。 save N to size
};

看来,如果此参数是typename或整数值,可以保存任何模板参数。事情是指向成员的指针是一个偏移量,即整数。
现在我想在编译时保存任何指向成员的指针:

  struct Foo {
int m ;
int r;
};

template< int Foo :: * ptr_to_member>
struct B {
//下一条语句不工作!
static int Foo :: * const saved_ptr_to_member = ptr_to_member;
};

//使用
的示例int main(){
typedef B<& Foo :: m> Bm;
typedef B<& Foo :: r> Br;
Foo foo;
std :: cout<< (foo。*(Bm :: saved_ptr_to_member));
}

如何在编译时将指针保存到成员 ?我使用VS2008。



注意。编译时间至关重要。请不要编写运行时解决方案。我知道。

解决方案

为什么要使用模板?

  #include< cstdio> 

struct Foo {
int a;
int b;
} foo = {2,3};

int const(Foo :: * mp)=& Foo :: b;

int
main(){
printf(%d \\\
,foo。* mp);
return 0;
}

以下编译 mp 到gcc-4.4.1(我目前没有访问MSVC):

  .globl mp 
.align 4
.type mp,@object
.size mp,4
mp:
.long 4



这只是对成员的一个偏移量,它看起来非常适合我的编译时间。



使用模板,您需要在类外指定定义:

  #include< cstdio& 

struct Foo {
int m;
int r;
} foo = {2,3};

template< int Foo :: * Mem>
struct B {
static int Foo :: * const mp;
};

template< int Foo :: * Mem>
int Foo :: * const B< Mem> :: mp = Mem;

int main(){
typedef B<& Foo :: m> Bm;
typedef B<& Foo :: r> Br;
printf(%d,%d \\\
,foo。*(Bm :: mp),foo。*(Br :: mp));
}

其中编译为:

  g ++ -O2 -S -o-b.cc | c ++ filt 

...

.weak B<&(Foo :: r)> :: mp
.section .rodata._ZN1BIXadL_ZN3Foo1rEEEE2mpE ,aG,@ progbits,B<&(Foo :: r)> :: mp,comdat
.align 4
。 :: mp,@object
.size B<&(Foo :: r)> :: mp,4
B<&(Foo :: r)> :: mp:
.long 4
.weak B<&(Foo :: m)> :: mp
.section .rodata._ZN1BIXadL_ZN3Foo1mEEEE2mpE,aG,@ progbits,B<& Foo :: m)> :: mp,comdat
.align 4
.type B<&(Foo :: m)> :: mp,@object
.size B< ;&(Foo :: m)> :: mp,4
B&(Foo :: m)> :: mp:
.zero 4

然而,这一切都重新实现了标准库的功能(参见 std :: tr1 :: mem_fn )。


Consider the following code

template<typename T, int N>
struct A {
  typedef T value_type; // OK. save T to value_type
  static const int size = N; // OK. save N to size
};

Look, it is possible to save any template parameter if this parameter is a typename or an integer value. The thing is that pointer to member is an offset, i.e. integer. Now I want to save any pointer to member in compile time:

struct Foo {
   int m; 
   int r;
};

template<int Foo::*ptr_to_member>
struct B {
   // Next statement DOES NOT WORK!
   static int Foo::* const saved_ptr_to_member = ptr_to_member; 
};

// Example of using
int main() {
    typedef B<&Foo::m> Bm;
    typedef B<&Foo::r> Br;
    Foo foo;
    std::cout << (foo.*(Bm::saved_ptr_to_member));
}

How to save pointer to member in compile time? I use VS2008.

Note. Compile time is critical. Please don't write run-time solution. I know it.

解决方案

Why using a template?

#include <cstdio>

struct Foo {
    int a;
    int b;
} foo = {2, 3};

int const (Foo::*mp) = &Foo::b;

int
main() {
    printf("%d\n", foo.*mp);
    return 0;
}

The following compiles mp to this on gcc-4.4.1 (I don't have access to MSVC at the moment):

.globl mp
        .align 4
        .type   mp, @object
        .size   mp, 4
mp:
        .long   4

It is just an offset to the member, which looks pretty compile-time to me.

With template, you need to specify the definition outside of the class:

#include <cstdio>

struct Foo {
   int m;
   int r;
} foo = {2, 3};

template<int Foo::*Mem>
struct B {
   static int Foo::* const mp;
};

template<int Foo::*Mem>
int Foo::* const B<Mem>::mp = Mem;

int main() {
    typedef B<&Foo::m> Bm;
    typedef B<&Foo::r> Br;
    printf("%d, %d\n", foo.*(Bm::mp), foo.*(Br::mp));
}

Which compiles to:

g++ -O2 -S -o- b.cc | c++filt

...

        .weak   B<&(Foo::r)>::mp
        .section        .rodata._ZN1BIXadL_ZN3Foo1rEEEE2mpE,"aG",@progbits,B<&(Foo::r)>::mp,comdat
        .align 4
        .type   B<&(Foo::r)>::mp, @object
        .size   B<&(Foo::r)>::mp, 4
B<&(Foo::r)>::mp:
        .long   4
        .weak   B<&(Foo::m)>::mp
        .section        .rodata._ZN1BIXadL_ZN3Foo1mEEEE2mpE,"aG",@progbits,B<&(Foo::m)>::mp,comdat
        .align 4
        .type   B<&(Foo::m)>::mp, @object
        .size   B<&(Foo::m)>::mp, 4
B<&(Foo::m)>::mp:
        .zero   4

However this all smacks of standard library features reimplementation (see std::tr1::mem_fn).

这篇关于如何在编译时将指针保存到成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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