C++库研究笔记——使用函数模板还是类模板?+ 一个类型重复问题的两种解决方法

本文探讨了在设计库时选择模板类的两种方式:一种方便开发,另一种方便用户使用。通过比较分析,作者最终选择了更有利于开发的方式,并指出这可能带来的后续困难。同时,文章还提出了在尝试不同设计方案后的结论,即模板类的设计在实践中往往更为合适。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进行初步设计:

涉及的问题是:

template<typename T>
class Sin
{
public:
T operator()(T x){...};
};

Sin<float> sin;
float x;
sin(x);

Sin<double> sin;
float x;
sin(x);//error
///////////////////////////////////////////////////
class Sin
{
public:
template<typename T>
T operator()(T x){...};
};
Sin sin;
float x;
sin(x);
Sin sin;
double x;
sin(x);


哪个更好?

尽管看上去区别不大,但是设计库的时候,会有很大,或非常大的差别。
比较:
第一种会方便开发
第二种会方便用户使用

后面又进行了试探性的设计,还是决定从方便开发的角度选第一种class template, 选用第二种在开发中会带来一定的困难,甚至面读系统将来需要增加新的功能时,自己没有信心完成设计。


后面又进行了试探性的设计,还是决定从方便开发的角度选第一种class template, 选用第二种在开发中会带来一定的困难,甚至面读系统将来需要增加新的功能时,自己没有信心完成设计。
做了一些试探性的设计,发现确实class template 更好:

template <typename T>
class objective_function
{
public:
    typedef T   value_type;
    virtual ~objective_function();
    virtual size_t  dim() const =0;
    virtual T       operator() (const T * x, T * g=0)const =0;
    virtual bool    progress(int n, const T* x, T fx, const T * g,
                            T gnorm) const;
// 设计过于复杂
template<typename T, class FunObj>
class minimizer
{
public:
    typedef     T   value_type;
    virtual void do_get_direction(array1d<T>& d);
    void main_loop(array1d<T>& x)
    {
        array1d<T> d(x.size());

        T f;
        f=FunObj(x, g);
        progress();
        while(1)
        {
            do_get_direction(d);
            T t=get_initial_step();
            do_line_search(x, t, f, g, x_new, f_new, g_new);
            if(!(bool continue=progress()))
                break;
            if(bool stop=stop_if_optimal(g, f))
                break;
        }
    }
    virtual T do_get_step(T initial);
    virtual T get_initial_step();
    virtual void do_line_search(array1<T>& x,  T& t, T& f, array1d<T>& g);
    // virtual bool stop_if_optimal(const array1d<T>&g, T f);
    virtual bool progress();
};

// FunObj is FunObj<T>
template<typename T, class FunObj>
class minimizer
{
public:
    typedef     T   value_type;

FunObj<T>  本身含有T,这两个T 不是重复了?

 解决方法1: 类似的,可以这样写   把模板写成这样感觉很变态,难以阅读,不过确实有效

// 优点:保证T 与 FunObj<T> 完全一致

template <typename T, template<typename> class FunObj>
class minimizer<T, FunObj<T> >
// 类似的,可以这样写
// std::allocator<T>
template <template<class, class > class C, typename T>
void test(C<T,std::allocator<T> >& A, T x, int N)
{
    T v;
    v=A[0]*x;
    cout<<v<<endl;
}


解决方法2

youdian: // 优点明显:灵活使用,<int, FucObj<float> >  <double, FucObj<float> >
// 缺点也很明显: 比如涉及:1.0, FuncObj<float> , 1.0 默认的是double类型, 用户没有想把这些类都变成double类型,只是写掉了一个f, 1.0f, 但编译器不会报告错误

template <T1, T2>
struct larger_type
{
typedef T1	type;
}

template <>
struct larger_type<float, double>
{
typedef double	type;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值