3

重複の可能性:
インライン フレンド関数の範囲は?

簡単なプログラムを考えてみましょう:

template<typename T> struct foo{
friend void bar(){}
};

int main(){
foo<int>(); foo<float>();
}

上記のコードは ODR ルールに違反しています。なぜでしょうか? 、また、機能の範囲はどこbarですか?

4

3 に答える 3

1

friend関数はメンバー関数ではありません。クラス内で友情を宣言するだけですが、関数は常に自由関数です。クラス テンプレート クラス内で定義すると、テンプレート インスタンスの数だけ定義することになります。

それをコードで説明しようと思います。私たちの目的のために、あなたのコードはこれと同等です:

template<typename T> struct foo{
};

template<> struct foo<int>{
  friend void bar();
};

void bar() {};

template<> struct foo<double>{
  friend void bar();
};

void bar() {};

int main(){
  foo<int>(); foo<float>();
}
于 2012-11-08T16:13:28.743 に答える
1

あなたのコードは free 関数void bar()を 2 回定義しているため、つまり、テンプレートはインスタンス化ごとに という名前の新しい関数を生成し、毎回void bar()まったく同じシグネチャを持っているため、同じシグネチャを持つ複数の関数があり、これは違反です。 ODRの。

周囲の名前空間に名前を挿入するため、当面の手法は「Friend Name Injection」と呼ばれます。

于 2012-11-08T16:17:35.193 に答える
0

の内部を定義しました。これにより、テンプレートのインスタンス化ごとに1回、funcが二重に定義されます。あるエンティティの宣言にすぎないはずです。エンティティ自体(あなたの場合はfunc)は他の場所で定義する必要があります。定義を宣言に置き換えて、別の場所で定義してください。barstructbarFriendbarfriend void bar();bar

于 2012-11-08T16:09:01.540 に答える