首頁  >  問答  >  主體

c++ - 根据函数参数数目调用不同的函数

我现在需要对矩阵进行操作,这些操作的过程都是类似的,只是其中的一个算子不同。这些算子有些是对每个元素操作,有些是对相邻之间的进行操作,我尝试用以下的方法去把算子和步骤分离开来,但是问题是对于参数个数不同的情况怎么处理?能不能编译时就确定好该调用的函数?

#include <vector>
using namespace std;

template <typename OPER, typename T>
void executor(OPER op, vector<vector<T>>& m)
{
    //--- pre processing
    //...
    //---
    T last = T();
    for (auto& v : m){
        for (auto& a : v){
            // if(varnum == 1)
            op(a);            
            //if(varnum == 2)
            //op(a, last);    // fail
            last = a;
        }
    }
    //--- post processing
    //...
    //---
}


void f1(float& a)        
{
    a *= 2;
}
void f2(float& a, float b)    // fail 需要两个参数
{
    a -= b;
}

int main()
{
    vector<vector<float>> m;
    
    executor(f1, m);
    //executor(f2, m);    // fail

    return 0;
}
伊谢尔伦伊谢尔伦2714 天前565

全部回覆(3)我來回復

  • 天蓬老师

    天蓬老师2017-04-17 15:02:27

    剛好我也做過類似的矩陣庫https://github.com/codehz/mat...
    也有類似的問題,雖然我的需求不是前一個和後一個,而是單純的參數的不同
    我採取的解決方案是,透過回呼函數的參數清單自動決定-簡化如下

        template <typename F>
        real_t &for_each(F f) const
        {
            for(std::size_t row = 0; row < Rows; row++)
                for(std::size_t col = 0; col < Cols; col++)
                    if constexpr (function_traits<F>::arity == 1) f(data[row][col]);
                    else if constexpr (function_traits<F>::arity == 0) f();
                    else if constexpr (function_traits<F>::arity == 3) f(data[row][col], row, col);
                    else throw "for_each(const) failed";
            return static_cast<real_t &>(*this);
        }

    其中function_traits的程式碼在這裡用於在編譯期得到函數的相關資訊
    if constexpr是C++17的特性,如果去除constexpr後通不過編譯,可能得使用std::enable_if來解決。

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-17 15:02:27

    把多個參數放到結構體裡,用結構體指標當參數可行否?

    回覆
    0
  • 黄舟

    黄舟2017-04-17 15:02:27

    從你的程式碼上看有很多方案.
    f2的b是簡單就可以拿到的,那可以 executor(std::bind(f2, _1, 2), m);
    也可以

    auto b = 3;
    auto f2_ = [&b](auto& v) {
        return f2(std::forward<decltype(v)>(v), b);
    };
    executor(f2_, m);

    如果是其他的值,可以用std::enable_if去寫executor的重載,原理就是用SFINAE原則.

    回覆
    0
  • 取消回覆