简体   繁体   English

如何在C ++中打印方法指针的地址?

[英]How do I print the address of a method pointer in C++?

For example: 例如:

struct A { void m() { } };

void stream_print() {
  void(A::*p)(void) = &A::m;
  std::cerr << p << std::endl;
}

void printf_print() {
  void(A::*p)(void) = &A::m;
  fprintf(stderr, "%p", p);
}

The stream_print() function always prints "1", which is obviously not what I want. stream_print()函数总是打印“1”,这显然不是我想要的。 The printf_print does not compile because p cannot be casted to void*. printf_print无法编译,因为p无法转换为void *。

What I need is a unique identifier for a method pointer that I can store in a container. 我需要的是一个方法指针的唯一标识符,我可以存储在容器中。 I know this sounds like a bad idea, but I am developing a small toy for unit testing that can benefit from it. 我知道这听起来不错,但我正在开发一种可以从中受益的单元测试小玩具。 I am not worried about overloads of the method, I know how to get the pointer to a specific overload. 我不担心方法的重载,我知道如何获得指向特定重载的指针。

I am using g++ 4.4.3 with C++0x enabled. 我正在使用启用了C ++ 0x的g ++ 4.4.3。

Let me know if you have any doubts. 如果您有任何疑问,请告诉我。

Member function pointer is generally an object with non-trivial internal structure. 成员函数指针通常是具有非平凡内部结构的对象。 Which is why you can't print it using tools intended for printing primitive types. 这就是为什么你不能使用打印原始类型的工具打印它。 Casting the pointer to void * is not a viable approach, since the size of member pointer is generally larger than sizeof(void *) . 将指针强制转换为void *不是一种可行的方法,因为成员指针的大小通常大于sizeof(void *) Forcefully casting it to void * will in any case discard a portion of the pointer representation, thus no longer guaranteeing the uniqueness. 强制将其强制转换为void *将在任何情况下丢弃指针表示的一部分,从而不再保证唯一性。

If what you are looking for is a unique string generated from the pointer, you can reinterpret the pointer as a character array, and use the string representation of character values in the identifier. 如果您要查找的是从指针生成的唯一字符串,则可以将指针重新解释为字符数组,并使用标识符中字符值的字符串表示形式。 Something like 就像是

void (A::*p)(void) = &A::m;

for (size_t i = 0; i < sizeof p; ++i)
  printf("%d ", reinterpret_cast<char *>(&p)[i]);

printf("\n");

Though I'm not 100% sure I understand the question correctly, if some mapping from a member pointer to some unique id is needed, the following code might meet the purpose: 虽然我不是100%确定我正确理解了这个问题,但如果需要从成员指针到某个唯一ID的映射,则以下代码可能符合以下目的:

struct A {
  void f() {}
  void g( int ) {}
};

template< class T, T >
char* get_unique_id() {
  static char dummy;
  return &dummy;
}

int main() {
  set< char* >  s;
  s.insert( get_unique_id< decltype( &A::f ), &A::f >() );
  s.insert( get_unique_id< decltype( &A::g ), &A::g >() );
  s.insert( get_unique_id< decltype( &A::f ), &A::f >() );
  s.insert( get_unique_id< decltype( &A::g ), &A::g >() );
  cout<< s.size() <<endl; // prints 2
}

The call of get_unique_id is a little lengthy though... get_unique_id的调用虽然有点冗长......
Presumably some macro might help to make it simpler. 据推测,一些宏可能有助于使其更简单。

Hope this helps 希望这可以帮助

If it only needs to work with GCC, you could use this extension to extract a function pointer from a pointer to member function. 如果只需要使用GCC,则可以使用扩展从指向成员函数的指针中提取函数指针。

Here is an example: 这是一个例子:

#include <iostream>
#include <stdio.h>

struct A { void m() { } };

typedef void (*mptr)(A*);

int main()
{
    mptr p = (mptr)(&A::m);
    std::cerr << (void*)p << std::endl;
    fprintf(stderr, "%p\n", p);
}

Compile with -Wno-pmf-conversions to suppress the warning. 使用-Wno-pmf-conversions进行编译以抑制警告。

There is no portable way to do this. 没有可移植的方法来做到这一点。 But have you tried reinterpret_cast<void*>(p) ? 但你试过reinterpret_cast<void*>(p)吗?

I suspect stream_print is using std::operator<<(std::ostream&, bool) , since that's the only valid conversion for a pointer-to-member type. 我怀疑stream_print正在使用std::operator<<(std::ostream&, bool) ,因为这是指针到成员类型的唯一有效转换。 That would explain why you get 1 . 这可以解释为什么你得到1

I wouldn't expect printf_print to work, even if a compiler did allow passing a pointer-to-member-function through ... . 我不希望printf_print工作,即使编译器也允许指针传递到成员函数通过... There's no guarantee sizeof(p) == sizeof(void*) , which is often a practical minimum for getting "expected" non-standard results from va_arg . 没有保证sizeof(p) == sizeof(void*) ,这通常是从va_arg获得“预期的”非标准结果的实际最小值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM