Ale*_*tov 6 c++ templates pointer-to-member
请考虑以下代码
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
};
Run Code Online (Sandbox Code Playgroud)
看,如果此参数是typename或整数值,则可以保存任何模板参数.问题是指向成员的指针是一个偏移量,即整数.现在我想在编译时保存任何指向成员的指针:
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));
}
Run Code Online (Sandbox Code Playgroud)
如何在编译时保存指向成员的指针?我用的是VS2008.
注意.编译时间至关重要.请不要编写运行时解决方案.我知道.
为什么使用模板?
#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;
}
Run Code Online (Sandbox Code Playgroud)
以下内容mp在 gcc-4.4.1 上编译为此内容(我目前无法访问 MSVC):
.globl mp
.align 4
.type mp, @object
.size mp, 4
mp:
.long 4
Run Code Online (Sandbox Code Playgroud)
它只是成员的偏移量,对我来说看起来相当编译时。
使用模板,您需要在类外部指定定义:
#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));
}
Run Code Online (Sandbox Code Playgroud)
编译为:
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
Run Code Online (Sandbox Code Playgroud)
然而,这一切都带有标准库功能重新实现的味道(请参阅 参考资料std::tr1::mem_fn)。