質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

6568閲覧

scandir関数を使ったファイルの検索について

tuyudaku

総合スコア75

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2018/01/12 08:35

編集2018/01/12 08:54

早速本題に入らせて貰います

C

1int is_event_device(const struct dirent *dir) 2{ 3 return strncmp("event", dir->d_name, 5) == 0; 4}

C

1struct dirent **namelist; 2int i, ndev; 3 4ndev = scandir("/dev/input", &namelist, is_event_device, alphasort);

大分省いてソースを書きましたが
このようなC言語のソースがあり、コンパイルも通り
問題なく動作することが確認できました

これを元に既にあるC++のプログラムに組み込もうと思い
以下のように変更しました

C++

1int クラス名::is_event_device(const struct dirent *dir) 2{ 3 return strncmp("event", dir->d_name, 5) == 0; 4}

変更といいましても、使用したいクラス内に組み込んだだけなので
クラス関数(メソッド?)として追加しただけなのですが
これをコンパイルするとエラーになってしまいました。
エラーはint型をint ()(struct dirent)型に変換できないという内容でした

これをクラス外で宣言してソースの「クラス名::」の部分を消すだけで
コンパイルが通るようになりました。
出来ればこれをクラス関数として使いたいため解決法が分かる方居ましたら
教えていただけませんでしょうか?

出来ればこういうエラーになってしまう原因なども分かりましたら教えていただけると嬉しいです。
関数とクラス関数は似ているようで別物なのでしょうか

以上、よろしくお願いいたします

----------追記--------------
クラス宣言

C++

1//ファイル名:クラス名.h 2namespace 名前 3{ 4 5//---------------------------------------------------------------------------- 6// クラス宣言. 7//---------------------------------------------------------------------------- 8class クラス名 9{ 10//---------------------------------------------------------------------------- 11// 定数定義. 12//---------------------------------------------------------------------------- 13 14 15//---------------------------------------------------------------------------- 16// メンバ関数. 17//---------------------------------------------------------------------------- 18// 公開メンバ関数. 19public: 20 21 22// 非公開メンバ関数. 23private: 24 int is_event_device(const struct dirent *dir) 25 26//---------------------------------------------------------------------------- 27// メンバ変数. 28//---------------------------------------------------------------------------- 29// 非公開メンバ変数. 30private: 31 32}; 33 34} // namespace 名前

エラー文は
「cannot convert '名前::クラス名::is_event_device' from type 'int (名前::クラス名::)(const dirent*) to type 'int ()(const dirent)'」
です

エラーが出ているのは
ndev = scandir("/dev/input", &namelist, is_event_device, alphasort);
のところです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2018/01/12 08:43

C++のクラスの宣言も記載下さい。エラーメッセージはコピペして下さい。エラーメッセージが出ている行も示して下さい。
tuyudaku

2018/01/12 08:55

申し訳ありません、補足したのでよろしくお願いいたします。コード内に日本語で書いてある部分は会社のソースのため特定されそうな部分は置き換えてあります。分かりづらくて申し訳ありませんが、よろしくお願いいたします...
guest

回答3

0

(追記2)
試してみてコンパイルが通ったので、コードを載せておきます。

c++

1class scandirTest 2{ 3public: 4 void callScandir(void){ 5 struct dirent **namelist; 6 int i, ndev; 7 ndev = scandir("/dev/input", &namelist, is_event_device, NULL); 8 } 9private: 10 static int is_event_device(const struct dirent *dir){ 11 return strncmp("event", dir->d_name, 5) == 0; 12 } 13}; 14 15int main(void){ 16 class scandirTest *p = new scandirTest(); 17 p->callScandir(); 18} 19

(追記1)
すみません、良く調べずに回答してしまいました。
is_event_deviceはscandirのコールバックとして登録するのですね。
出直します・・・。

以下は忘れてください。

クラスの宣言部分を追記いただいた方が、より良い回答が得られると思います。

勘ですが、そもそもis_event_device関数に渡している変数が間違っていませんか?
エラーメッセージの解釈が正しいのであれば、渡されている変数の型はint型だと言っています。
しかしis_event_device関数はstruct dirent *型を受け取りたいはずです。
scandir関数の戻り値ndevを渡してたりしないでしょうか。
*namelistを渡していますか?

投稿2018/01/12 08:57

編集2018/01/12 09:26
ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tuyudaku

2018/01/12 09:01

そこが間違っている場合、C言語のコンパイラでも通らないと思っているのですが やはり言語が違うと変わってくるのでしょうか... 自分でも試行錯誤しながら回答を待ちたいと思います 回答ありがとうございました
tuyudaku

2018/01/12 09:03

いえ、わざわざありがとうございます 単純そうで意外と深い部分の問題な気がしてとても困っています 回答ありがとうございました
ttyp03

2018/01/12 09:21

試してみました。 ただ、出力されるエラーが異なり、static関数でないとダメと言われたので、static宣言しましたところ、コンパイルは通りました インスタンス化されていないものをコールバックの対象にはできないでしょうから当然ですね。 こうしました↓ static int is_event_device(const struct dirent *dir)
ttyp03

2018/01/12 09:27

コードを追記しましたので参考にしてみてください。
tuyudaku

2018/01/15 02:56

とりあえずstaticにして試してみましたが 「cannot declare member function 'static int 名前::クラス名::is_event_device(const dirent*)' to have static linkage」 というエラーが出てしまいました。 何が違うのでしょうか... 皆様のアドバイスを参考にもう少し試行錯誤してみたいと思います 回答ありがとうございました。
guest

0

他の方が説明されていますが、

変更といいましても、使用したいクラス内に組み込んだだけなのでクラス関数(メソッド?)として追加しただけなのですが

「関数」を「メンバ関数」という別の物へかえてしまったのですから大問題です。「だけ」じゃありません。

エラー文は「cannot convert '名前::クラス名::is_event_device' from type 'int (名前::クラス名::)(const dirent*) to type 'int ()(const dirent)'」です

といいますが、(名前::クラス名::)は(名前::クラス名::*)のはずです。
エラーメッセージは正確に載せるべきです。
といいますか、このエラーメッセージに「メンバ関数へのポインタ」は「関数へのポインタ」に変換できませんと、はっきり書いてあります^^
クラスのメンバ関数へのポインタについては、C++の基礎なので、参考書をみてください。

投稿2018/01/12 12:33

colonq

総合スコア88

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

こんにちは。

出遅れました。ttyp03さんが回答されている通りstatic関数でないことが原因です。

非staticなメンバ関数は、内部的に this をパラメータで受け取っています。(コンパイラがこっそり付けてます。呼び出し側と呼び出される側両方にです。)
C言語にはそのような機能はありませんので、C言語のコールバック関数を呼ぶことを想定しているライブラリは、当然、thisを渡さないで呼び出しますから、引数リストがずれて異常動作します。それが自明ですので、事前にコンパイラがエラーにしているということなのです。

投稿2018/01/12 10:00

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tuyudaku

2018/01/15 02:56

とりあえずstaticにして試してみましたが 「cannot declare member function 'static int 名前::クラス名::is_event_device(const dirent*)' to have static linkage」 というエラーが出てしまいました。 何が違うのでしょうか... 皆様のアドバイスを参考にもう少し試行錯誤してみたいと思います 回答ありがとうございました。
Chironian

2018/01/15 03:43

staticを付ける場所が違います。 クラスを宣言している側に付けて下さい。 関数定義側には付けてはいけません。
tuyudaku

2018/01/15 03:48

はい、ごめんなさい 私もそれに気付いてたった今修正したところでした... わざわざ回答ありがとうございます 分かっていたことですが、自分自身の勉強不足ぶりが遺憾なく発揮されて 落ち込むばかりです... ChironianさんのC++講座がかなり興味深かったので これを機に暇な時間(仕事中)に読み進めたいと思います 買って全然読んでない参考書も読み進めたいです... なんとか問題は解決できそうです ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問