[c++] クラス宣言内にフレンド関数の実態を定義する際の挙動について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
かわうそ

[c++] クラス宣言内にフレンド関数の実態を定義する際の挙動について

#1

投稿記事 by かわうそ » 8年前

クラス宣言内部にフレンド関数の実態を記述できる関数とできない関数があることに気づいたのですが、何か制限があるのでしょうか?

 ***

☆詳しい質問
(コードを見てもらった方が早いかもしれません)

自作クラスMyClassのフレンド関数としてfunc1, func2, func3を用意しました。
それぞれの違いは、

 func1 … MyClass宣言内でプロトタイプを宣言。外部に実態を記述。引数はなし。
 func2 … MyClass宣言内で実態を記述。引数にフレンド関数がアクセスできるクラスを持つ。
 func3 … MyClass宣言内で実体を記述。引数はなし。

です。このときfunc3はコンパイルエラーとなります。
エラーの内容はC3861(識別子が見つからない)とC2672(一致するオーバーロード関数が見つからない)で、どうやらfunc3の関数が見えていないようです。

そこで質問です。

 1.フレンド関数の引数にそのフレンド関数がアクセスできるクラスを渡さない場合でも、クラス宣言内に実態を定義することは可能なのでしょうか。
 2.1が可能なら、その正しい書き方はどういうものでしょうか。
 (3).私の検索できる範囲でいろいろ見たつもりなのですが、このようなフレンド指定子の言語仕様、細かい挙動の説明、またマイナーな書式・使い方を紹介しているページがあればお教えください。

お願いします。。。


以下コード。

コード:

#include <string>
#include <iostream>

using namespace std;

class MyClass
{
public:
	MyClass() {}
	~MyClass() {}

	friend void func1();
	friend void func2(MyClass cls) { cout << "func2" << endl; }
//	friend void func3() { cout << "func3" << endl; }
};

void func1() { cout << "func1" << endl; }

void main()
{
	MyClass cls;

	func1();	//OK. 実体をクラス外に記述
	func2(cls);	//OK. インラインのフレンド関数.引数にフレンド関数がアクセスできるクラスを持つ
//	func3();	//コンパイルエラー.インラインのフレンド関数.引数なし

	return;
}

//EOF


かわうそ

Re: [c++] クラス宣言内にフレンド関数の実態を定義する際の挙動について

#3

投稿記事 by かわうそ » 8年前

なるほどー!
プロトタイプ宣言すればよかったのですね。

コード:

#include <string>
#include <iostream>

using namespace std;

void func3();  //プロトタイプ宣言

class MyClass
{
public:
	MyClass() {}
	~MyClass() {}

	friend void func3() { cout << "func3" << endl; }
};

void main()
{
	MyClass cls;
	func3();

	return;
}
確かにうまくゆきました。
hogeさんありがとうございます。

ADL、日本語では実引数依存の名前探索と言うそうですね。
https://ja.wikipedia.org/wiki/%E5%AE%9F ... 2%E7%B4%A2

引数をもとに関数が探されるという話は少しだけ聞いたことがありますが、そのように呼ばれることは今知りました。
これから詳しく調べて知っておこうと思います。

この質問に関しては解決です。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る