2016-04-25 10 views
8

ハッシングの一環として、関数ポインタを文字列表現に変換する必要があります。グローバル/静的関数で、それは些細です:メンバ関数の文字列表現を取得する方法は?

string s1{ to_string(reinterpret_cast<uintptr_t>(&global)) }; 

そしてhereから:

2)任意のポインタが に十分な大きさの任意の整数型に変換することができますがstd::uintptr_t(例えばポインタの値を保持します)

しかし、私はメンバ関数に問題があります。

cout << &MyStruct::member; 

出力は1ですが、デバッガではそのアドレスを見ることができます。

string s{ to_string(reinterpret_cast<uintptr_t>(&MyStruct::member)) }; 

コンパイル時にエラーcannot convertが返されます。だから、どのポインタも変換できないようです。

文字列表現を得るために他に何ができますか?

+0

「1」は正しい値かもしれません。結局、メンバ関数ポインタは相対的なものです。これはまた、型自体のtypeidのハッシュのような追加情報を追加しないと、多くの衝突に遭遇する可能性があることを意味します。そして、あなたが*どのポインタも変換できない*と言うとき、メンバ関数ポインタ*はポインタではないことを覚えておいてください。それらは正確に*メンバー関数ポインタ*です。 –

+1

"ポインタは変換できないようです... ..."ポインタはメンバへのポインタと同じではなく、ポインタは整数型に変換でき、メンバへのポインタは変換できません。 – user657267

+5

メンバーへのポインタのための 'operator <<'はありません。 '&MyStruct :: member'はnullでないメンバへのポインタです。どのポインタも 'bool'に暗黙的に変換できます。 NULLでないポインタは 'true'に変換され、デフォルトで' 1'として出力されます。 – molbdnilo

答えて

4
cout << &MyStruct::member; 

出力1デバッガで私がアドレスを見ることができますが。

ostream::operator<<(decltype(&MyStruct::member))のオーバーロードはありません。しかし、メンバ関数ポインタは暗黙的にboolに変換可能であり、そのために過負荷が存在し、これは過負荷解決に最適です。ポインタがnullでない場合、変換された値はtrueです。 true1として出力されます。


string s{ to_string(reinterpret_cast<uintptr_t>(&MyStruct::member)) }; 

コンパイル時エラーが変換することはできません提供します。だから、どのポインタも変換できないようです。

おそらく紛らわしい、standardeseにポインタは、オブジェクトポインタ、ポインタ・ツー・メンバー、ポインタ・ツー・機能とポインタ・ツー・メンバ関数のための包括的用語ではありません。ポインタとは、データポインタだけを意味します。

したがって、引用符付きの規則は、メンバー関数へのポインタには適用されません。これは(オブジェクト)ポインタにのみ適用されます。


私は、文字列表現を取得するために他に何ができますか?

unsigned charのバッファを使用して、ポインタを表すのに十分な大きさで、std::memcpyを使用できます。次に、あなた自身の選択の形でそれを印刷します。私は16進をお勧めします。

Martin Bonnerが指摘しているように、メンバへのポインタにはパディングが含まれていることがあります。その場合、同じメンバを指し示す2つの値が実際にバッファ内の異なる値を持つことがあります。したがって、実装されているどのビット(ある場合)がパディングであるかを知らなければ、2つの値が比較できないため、印刷された値はあまり使用されません。私が使用することはできませんので、このパディングのよう


は、残念ながら、私は、堅牢なソリューションを必要としています。

いいえポータブル堅牢なソリューションが存在します。

Jonathan Wakelyが指摘しているように、Itanium ABIにはパディングはありません。そのため、コンパイラがこれを使用する場合は、memcpyメソッドが機能します。

+0

* pointer-to-member *のデータの一部は、パディングスペースとして無視される可能性があります。その場合、同じメンバへのポインタを含むさまざまな変数が異なるパディング値を持つことがあります。これを16進数で印刷すると、(誤って)異なるハッシュが生成されます。私はこれがコンパイラのサポートなしで(一般的に)解決できる問題であるとは確信していません。 (もちろん実際にはあなたの提案はうまくいくでしょう) –

+0

@MartinBonner良い点。私は、どのようなニキタブラックが文字列表現を使用しているのか考えなかった。 – user2079303

+0

ありがとうございます。残念ながら、私は堅牢なソリューションが必要なので、私はこのパディングを使用することができません。さらに、私はそれをコピーする方法を知らない。 'memcpy'はソースとして' void * 'を受け入れますが、* pointer-to-member *はそれに変換することはできません。 – nikitablack

関連する問題