web-dev-qa-db-ja.com

異なるパラメーターを持つstd :: functionを同じ関数に渡す方法

統合しようとしている関数が3つあります。

それぞれが最初のパラメーターとしてstd::functionを取り、それをtry/catchブロック内で実行します。

問題は、3つの異なるタイプの関数があることです。パラメータのない関数、1つの整数パラメータを持つ関数、2つの整数パラメータを持つ関数。整数パラメーターを持つものには、対応するパラメーターが元の関数を介して渡されます。

ご覧のとおり、各関数はほぼ同じなので、すべてをマージできるといいですね。ただし、どのような形式のstd::functionでも受け取ることができるパラメーターを設定する方法が不明であり、使用する対応するデータが提供されているという事実に依存しています。

ここに関数があります:

void run_callback(std::function<void()>& func) {
    try {
        func();
    } catch(const std::exception& ex) {
        print_callback_error(ex.what());
    } catch(const std::string& ex) {
        print_callback_error(ex.c_str());
    } catch(...) {
        print_callback_error();
    }
}

void run_callback_int(std::function<void(int)>& func, int data) {
    try {
        func(data);
    } catch(const std::exception& ex) {
        print_callback_error(ex.what());
    } catch(const std::string& ex) {
        print_callback_error(ex.c_str());
    } catch(...) {
        print_callback_error();
    }
}

void run_callback_intint(std::function<void(int, int)>& func, int data1, int data2) {
    try {
        func(data1, data2);
    } catch(const std::exception& ex) {
        print_callback_error(ex.what());
    } catch(const std::string& ex) {
        print_callback_error(ex.c_str());
    } catch(...) {
        print_callback_error();
    }
}

どんな提案も大歓迎です!

9
Griffort

可変テンプレートで動作するようです。

何かのようなもの:

template <typename ... Args>
void run_callback(std::function<void(Args...)> const & func, Args ... as) {
    try {
        func(as...);
    } catch(const std::exception& ex) {
        print_callback_error(ex.what());
    } catch(const std::string& ex) {
        print_callback_error(ex.c_str());
    } catch(...) {
        print_callback_error();
    }
}

または(可能な転送を管理する方が良いかもしれません)

template <typename ... FArgs, typename ... Args>
void run_callback(std::function<void(FArgs...)> const & func,
                  Args && ... as) {
    try {
        func(std::forward<Args>(as)...);
    } catch(const std::exception& ex) {
        print_callback_error(ex.what());
    } catch(const std::string& ex) {
        print_callback_error(ex.c_str());
    } catch(...) {
        print_callback_error();
    }
}
11
max66

ラムダ関数を使用することをお勧めします:

void run_callback(std::function<void()>& func) {
    try {
        func();
    } catch(const std::exception& ex) {
        print_callback_error(ex.what());
    } catch(const std::string& ex) {
        print_callback_error(ex.c_str());
    } catch(...) {
        print_callback_error();
    }
}

この関数を呼び出すには:

run_callback([]{ func_without_params(); });

または

run_callback([&]{ func_with_1_param(a); });

等々

1