8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C, C++ の関数ポインタ 自分用メモ

Last updated at Posted at 2025-02-07

いつも忘れてしまうので、自分用メモ

1.基本形

sample1.c
#inclide <stdio.h>
double Calc(int a, double f)
{
    return a * f;
}

int main()
{
    // 初期化
    double (*pFunc)(int, double) = Calc;

    // 実行
    double result = (*pFunc)(3, 2.5);
    printf("%f\n", result);
}

2. C++ クラス内のメンバ関数を関数ポインタで扱いたい

sample2.cpp
#include <iostream>

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

    void FuncAll()
    {
        // 初期化
        int (CHoge:: * pFunc1)(int) = &CHoge::func1;
        int (CHoge:: * pFunc2)(int) = &CHoge::func2;
        int (CHoge:: * pFunc3)(int) = &CHoge::func3;

        // 実行
        std::cout << (this->*pFunc1)(3) << std::endl;
        std::cout << (this->*pFunc2)(1) << std::endl;
        std::cout << (this->*pFunc3)(4) << std::endl;
    }

private:
    int func1(int n) { return n; }
    int func2(int n) { return n * 2; }
    int func3(int n) { return n * 3; }
};

int main()
{
    CHoge hoge;
    hoge.FuncAll();
}

3. vector で回してみる

sample3.cpp
#include <iostream>
#include <vector>

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

    void FuncAll()
    {
        // 初期化
        std::vector<int (CHoge::*)(int)> vecFuncPtr = {
            &CHoge::func1,
            &CHoge::func2,
            &CHoge::func3,
        };
        
//      auto の方が楽
//      for (int (CHoge::* pFunc)(int) : vecFuncPtr) {
        for (auto pFunc : vecFuncPtr) {
            std::cout << (this->*pFunc)(3) << std::endl;
        }
    }

private:
    int func1(int n) { return n; }
    int func2(int n) { return n * 2; }
    int func3(int n) { return n * 3; }
};

int main()
{
    CHoge hoge;
    hoge.FuncAll();
}

4. std::function, bind を使ってみる

sample4.cpp
#include <iostream>
#include <functional>

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

    void FuncAll()
    {
        // 初期化
        auto tfunc1 =
            std::bind(&CHoge::func1, this, std::placeholders::_1);
        auto tfunc2 =
            std::bind(&CHoge::func2, this, std::placeholders::_1);
        auto tfunc3 =
            std::bind(&CHoge::func3, this, std::placeholders::_1);

        // 実行
        std::cout << tfunc1(3) << std::endl;
        std::cout << tfunc2(1) << std::endl;
        std::cout << tfunc3(4) << std::endl;
    }

private:
    int func1(int n) { return n; }
    int func2(int n) { return n * 2; }
    int func3(int n) { return n * 3; }
};

int main()
{
    CHoge hoge;
    hoge.FuncAll();
}

5. 同様に vector で回してみる

sample5.cpp
#include <iostream>
#include <functional>
#include <vector>

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

    void FuncAll()
    {
        // 初期化
        std::vector< std::function<int(int)> > vecFunction =
        {
            std::bind(&CHoge::func1, this, std::placeholders::_1),
            std::bind(&CHoge::func2, this, std::placeholders::_1),
            std::bind(&CHoge::func3, this, std::placeholders::_1),
        };

        // 実行
        //  for (std::function<int(int)> tFunc : vecFunction) {
        for (auto tFunc : vecFunction) {
            std::cout << tFunc(3) << std::endl;
        }
    }

private:
    int func1(int n) { return n; }
    int func2(int n) { return n * 2; }
    int func3(int n) { return n * 3; }
};

int main()
{
    CHoge hoge;
    hoge.FuncAll();
}

6. ラムダ式で書いてみる

sample6.cpp
#include <iostream>
#include <functional>

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

    void FuncAll()
    {
        // 初期化
        auto lamda1 = [this](int i) { return func1(i); };
        auto lamda2 = [this](int i) { return func2(i); };
        auto lamda3 = [this](int i) { return func3(i); };

        // 実行
        std::cout << lamda1(3) << std::endl;
        std::cout << lamda2(1) << std::endl;
        std::cout << lamda3(4) << std::endl;
    }

private:
    int func1(int n) { return n; }
    int func2(int n) { return n * 2; }
    int func3(int n) { return n * 3; }
};

int main()
{
    CHoge hoge;
    hoge.FuncAll();
}

7. ラムダ式で書いて vector

sample7.cpp
#include <iostream>
#include    <vector>
#include    <functional>

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

    void FuncAll()
    {
        // 初期化
        std::vector<std::function<int(int)>> vecFunc = {
            [this](int i) { return func1(i); },
            [this](int i) { return func2(i); },
            [this](int i) { return func3(i); },
        };

        // 実行
        for(auto func : vecFunc) {
            std::cout << func(3) << std::endl;
        }
    }

private:
    int func1(int n) { return n; }
    int func2(int n) { return n * 2; }
    int func3(int n) { return n * 3; }
};

int main()
{
    CHoge hoge;
    hoge.FuncAll();
}

8.ラムダ式 別解1

こんな書き方もあるよと。そろそろ main() は省きます。

sample8.cpp
class CHoge
{
public:
    CHoge() {}
    ~CHoge() {}

    void FuncAll()
    {
        // 初期化
        auto pFunc1 = [](CHoge* p, int n) { return p->func1(n); };
        auto pFunc2 = [](CHoge* p, int n) { return p->func2(n); };
        auto pFunc3 = [](CHoge* p, int n) { return p->func3(n); };

        // 呼び出し
        std::cout << pFunc1(this, 1) << std::endl;
        std::cout << pFunc2(this, 2) << std::endl;
        std::cout << pFunc3(this, 3) << std::endl;
    }

private:
    int func1(int n) { return n; }
    int func2(int n) { return n * 2; }
    int func3(int n) { return n * 3; }
};

9.ラムダ式別解2

sample9.cpp

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

    void FuncAll()
    {
        // 初期化
        std::vector<std::function<int(CHoge*, int)>> vecFunc = {
            { [](CHoge* p, int n) { return p->func1(n); } },
            { [](CHoge* p, int n) { return p->func2(n); } },
            { [](CHoge* p, int n) { return p->func3(n); } },
        };

        // 呼び出し
        for (auto func : vecFunc) {
            std::cout << func(this, 3) << std::endl;
        }
    }

private:
    int func1(int n) { return n; }
    int func2(int n) { return n * 2; }
    int func3(int n) { return n * 3; }
};

10.感想

う~ん。どうだろ? 僕は昔の書き方(sample2, sample3)で慣れ親しんだのでつい書いちゃうけど、今風なら sample6, sample7 あたりがすっきりしているかな。

8
2
34

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?