针对不同数据类型的单一结构调整方法

Single struct adjusting methods to different data types

本文关键字:单一 结构调整 方法 数据类型      更新时间:2023-10-16

我有四个非常相似的结构体(非常简单地说明问题),不同的参数类型

using state_type = std::vector<double>;
struct foo {
    double _x;
    double _y;
    foo (double x, double y) : _x{x}, _y{y} {}
    void operator() (const state_type &v, state_type &u) const {
       for (auto i=0; i<v.size(); i++)
          u[i] = x * v[i] + y * v[i];
    }
}
struct foo {
    state_type _x;
    double _y;
    foo (state_type x, double y) : _x{x}, _y{y} {}
    void operator() (const state_type &v, state_type &u) const {
       for (auto i=0; i<v.size(); i++)
          u[i] = x[i] * v[i] + y * v[i];
    }
}
struct foo {
    double _x;
    state_type _y;
    foo (double x, state_type y) : _x{x}, _y{y} {}
    void operator() (const state_type &v, state_type &u) const {
       for (auto i=0; i<v.size(); i++)
          u[i] = x * v[i] + y[i] * v[i];
    }
}
struct foo {
    state_type _x;
    state_type _y;
    foo (state_type x, state_type y) : _x{x}, _y{y} {}
    void operator() (const state_type &v, state_type &u) const {
       for (auto i=0; i<v.size(); i++)
          u[i] = x[i] * v[i] + y[i] * v[i];
    }
}

是否有一种方法可以只使用一个结构体,根据参数的类型自动选择正确的结构体?

我将使用模板和辅助函数来推断类型,然后针对各种类型组合对operator()进行专门化。一个非常简单的例子来说明这一点:

#include <iostream>
#include <vector>
using state_type = std::vector<double>;
template<typename T, typename S>
struct X
{
    T _a;
    S _b;
    X(T a, S b): _a(a), _b(b){}
    // specialize this for different types
    void operator()(const state_type& v, state_type& u) const 
    {
        std::cout << "default implementationn";
    }
};
// specializations of operator() for <state_type, double> 
template<>
void X<state_type, double>::operator()(const state_type& v, state_type& u) const
{
    std::cout << "<state_type, double> functorn";
}
template<typename T, typename S>
X<T,S> make_X(const T& a, const S& b)
{
    return X<T,S>(a,b); // or even return {a, b};
}
int main()
{
    state_type st;
    auto foo_double_statetype = make_X(st, 42.); // makes X<state_type, double>
    foo_double_statetype(st, st); // calls the specialized operator()
    auto foo_int_int = make_X(42, 42); // makes X<int, int>
    foo_int_int(st, st); // calls the default operator() (non-specialized)
}

Live on Coliru