C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: 関数ポインタに同クラスのメンバー関数を使う場合


(過去ログ 108 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■64540 / inTopicNo.1)  関数ポインタに同クラスのメンバー関数を使う場合
  
□投稿者/ OROCHI (14回)-(2012/12/06(Thu) 11:20:52)

分類:[C/C++] 

こんにちは

現在、以下のようなコードを書いています
class Ex1
{
public:
    Ex1(){};
    ~Ex1(){};
    int odd(int val) 
    {
       (略)
    }
    int even(int val) 
    {
       (略)
    }
    int filter(int (*func)(int), int *items, int *results, int n)
    {
       (略)
    }
    void Ex1Done()
    {
       int items[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
       int odds[9] = {0};
       int evens[9] = {0};
       int i, n;

       /* 配列の中身を表示 */
       for ( i = 0; i < 9; i++ )  printf("%d ", items[i]);
       printf("\n");

       /* 偶数のデータのみを取得 */
       n = filter(&Ex1::odd, items, odds, 9);

       (略)
    }    
}

コンパイル時にfilerの部分でエラー	
1	error C2664: 'Ex1::filter' : 1 番目の引数を 'int (__thiscall Ex1::* )(int)' から 'int (__cdecl *)(int)' に変換できません。(新しい機能 ; ヘルプを参照)	
と出てきます。同じメンバの関数を関数ポインタに使う場合、上手い手はないものでしょうか?
グローバルな関数にしろと言われればそれまでなのですが、仕様の都合で、同じクラスで完結させてくれと言われていまして・・・

引用返信 編集キー/
■64541 / inTopicNo.2)  Re[1]: 関数ポインタに同クラスのメンバー関数を使う場合
□投稿者/ howling (136回)-(2012/12/06(Thu) 12:11:58)
No64540 (OROCHI さん) に返信

ちょうど知らないことだったので調べてみました。
C++ 関数ポインタでググって一番上に出るここ参照で。

http://www.geocities.jp/ky_webid/cpp/language/034.html

私もサンプルで作って同じエラーが出たので、
上のURLと異なる点を探したところ、

int hoge(int (*pFunc)(int))



int hoge(int (Ex1::*pFunc)(int))

これですねー。では。
引用返信 編集キー/
■64542 / inTopicNo.3)  Re[1]: 関数ポインタに同クラスのメンバー関数を使う場合
□投稿者/ Hongliang (24回)-(2012/12/06(Thu) 12:13:09)
funcで使う関数が他のEx1のメンバを使用しないなら、funcで使う関数をstaticにすればいいでしょう。

他のメンバにアクセスするなら、メンバ関数ポインタを使います。
int filter(int (Ex1::*func)(int), int *items, int *results, int n)
{
    (略)
    int y = (this->*func)(x);
    (略)
}

引用返信 編集キー/
■64543 / inTopicNo.4)  Re[1]: 関数ポインタに同クラスのメンバー関数を使う場合
□投稿者/ επιστημη (30回)-(2012/12/06(Thu) 12:27:03)
επιστημη さんの Web サイト
...こんなもんでどうでしょね。

#include <cstdio>
#include <iostream>
using namespace std;

class Ex1 {
public:
  Ex1(){};
  ~Ex1(){};
  int odd(int val) {
    return val % 2 != 0;
  }
  int even(int val) {
    return val %2 == 0;
  }
  int filter(int (Ex1::*func)(int), int *items, int *results, int n) {
    int count;
    for ( count = 0; 0 < n; --n ) {
      if ( (this->*func)(*items) ) {
        *results++ = *items;
        ++count;
      }
      ++items;
    }
    return count; 
  }
  void Ex1Done() {
       int items[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
       int odds[9] = {0};
       int evens[9] = {0};
       int i, n;

       /* 配列の中身を表示 */
       for ( i = 0; i < 9; i++ )  printf("%d ", items[i]);
       printf("\n");

       /* 偶数のデータのみを取得 */
       n = filter(&Ex1::odd, items, odds, 9);
       for ( i = 0; i < n; i++ )  printf("%d ", odds[i]);
       printf("\n");
       
       /* 奇数のデータのみを取得 */
       n = filter(&Ex1::even, items, evens, 9);
       for ( i = 0; i < n; i++ )  printf("%d ", evens[i]);
       printf("\n");
       
    }    
};

int main() {
  Ex1 e;
  e.Ex1Done();
}

引用返信 編集キー/
■64544 / inTopicNo.5)  Re[2]: 関数ポインタに同クラスのメンバー関数を使う場合
□投稿者/ OROCHI (15回)-(2012/12/06(Thu) 12:36:01)
> int hoge(int (*pFunc)(int))
> 
> ↓
> 
> int hoge(int (Ex1::*pFunc)(int))
> 
> これですねー。では。

ありがとうございました、とりあえず以下のように修正しました
・・・同じとこ見たのにこの答えにたどり着けませんでした(汗)


int filter(int (Ex1::*func)(int), int *items, int *results, int n)
が、今度は内部でfuncを使おうとすると
エラー	1	error C2064: 1 引数を取り込む関数には評価されません
と出ます。内部はこんな感じです
int filter(int (Ex1::*func)(int), int *items, int *results, int n)
{
	int i, j = 0;
	for(i = 0; i < n; i++) 
	{
		if (func(items[i])) // ここでエラー
		{
			results[j++] = items[i];
		}
	}
	return j;
}
こっちはわかる方いらっしゃいますでしょうか?	

引用返信 編集キー/
■64545 / inTopicNo.6)  Re[3]: 関数ポインタに同クラスのメンバー関数を使う場合
□投稿者/ επιστημη (31回)-(2012/12/06(Thu) 12:41:52)
επιστημη さんの Web サイト
2012/12/06(Thu) 13:04:50 編集(投稿者)

> if (func(items[i])) // ここでエラー

No64542 , No64543 にコタエあるのに....
引用返信 編集キー/
■64546 / inTopicNo.7)  Re[4]: 関数ポインタに同クラスのメンバー関数を使う場合
□投稿者/ howling (137回)-(2012/12/06(Thu) 12:51:08)
No64545 (επιστημη さん) に返信

横からすみません。
また、話がかなり脱線します。すみません。

for ( count = 0; 0 < n; --n )

これ、普段こういう書き方したことなかったのですが、
このやり方良いですね…。

普段は、

for( int i = 0; i < n; i++ )

とやっているのですが、
中でint使わないのにカウンティングのためだけにiを作るのは微妙だよなー
と思うことがありました。(もちろん、内部でiを使うならいいんです)

企業の入社テストなんかでも、
「既存の関数○○と同じ実装をできるだけ短く書け」なんてのがあったりして、
回答を見て呆然とします。

「普段書いているから」でやると成長しませんからね…。
そういう知識も身につけていきたいものです。
引用返信 編集キー/
■64547 / inTopicNo.8)  Re[5]: 関数ポインタに同クラスのメンバー関数を使う場合
□投稿者/ επιστημη (32回)-(2012/12/06(Thu) 13:19:44)
επιστημη さんの Web サイト
# 脱線に次ぐ脱線

> 企業の入社テストなんかでも、
> 「既存の関数○○と同じ実装をできるだけ短く書け」なんてのがあったりして、
> 回答を見て呆然とします。

  int filter(int (Ex1::*func)(int), int *items, int *results, int n) {
    return std::copy_if(items, items+n, results,  [&,this](int n) -> bool { return (this->*func)(n) != 0; }) - results;
  }

引用返信 編集キー/
■64548 / inTopicNo.9)  Re[5]: 関数ポインタに同クラスのメンバー関数を使う場合
□投稿者/ OROCHI (16回)-(2012/12/06(Thu) 13:48:09)

> ■No64545 (επιστημη さん) に返信
すみません、リロードのタイミングのせいなのか64545に気づきませんでした
これで解決しました。ありがとうございます

> ■No64546 (howling さん) に返信
私自身失敗して原因究明に時間を割かれることを恐れて、新しいことをやろうとせずに慣れた手で済ませようとする癖があるのでそういうのは重要だと思います

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -