6

次の関数テンプレートを検討してください。

template<typename T>
unsigned long f(void *) { return 0;}

ここで、 と のアドレスを次のように出力f<A>f<B>ます。

std::cout << (void*)f<A> << std::endl;
std::cout << (void*)f<B> << std::endl;

MSVS10 でコンパイルした場合、同じアドレスが表示されるのはなぜですか? それらは 2 つの異なる機能ではないため、異なるアドレスを出力する必要がありますか?

更新しました:

ideone では、別のアドレスが出力されることに気付きました。関数はまったく依存しないため、MSVS10 はコードを最適化し、T同じ関数を生成します。これに関する@Markの回答とコメントは貴重です。:-)

4

3 に答える 3

7

にキャストする必要がありますvoid *:

std::cout << (void*)(ftype*)f<A> << std::endl;
std::cout << (void*)(ftype*)f<B> << std::endl;

関数ポインター (または非 void ポインターの他のいくつかのクラス) にキャストすると、 forboolによってとして解釈されます(したがって)。operator<<std::ostream1

于 2012-02-17T05:19:35.100 に答える
2

関数はテンプレート パラメーターに依存しないため、コンパイラはすべてのインスタンス化を 1 つの関数に凝縮できます。

1なぜあなたがアドレスを取得するのかわかりません。


Nawazによって追加されました:

実際のコードを試してみたところ、上記の @Mark がここで非常に重要であると結論付けました。

関数はテンプレート パラメーターに依存しないため、コンパイラはすべてのインスタンス化を 1 つの関数に凝縮できます。

T*また、関数本体がではなく に依存している場合でも、実際のコードでは異なる型引数に対して同じ関数を生成するという結論に達しましたT(ただし、ideone ではありません)。ただし、に依存している場合は、異なる型引数に対して (幸いなことに) 異なるTため、異なる関数が生成されます。sizeof(T)

そこで、関数テンプレートに型のダミーの自動変数 を追加しTて、関数が のサイズに依存し、T異なる関数を強制的に生成できるようにしました。

于 2012-02-17T05:20:32.227 に答える
1

関数へのポインターをオブジェクト型へのポインターにキャストした結果は未定義であるため、これは単に未定義の動作のケースです。

調べるより興味深い式は、 if と if のみにf<A> == f<B>評価され、同じ型を参照する必要があるということです。trueAB

于 2012-02-17T06:57:27.777 に答える