您的位置:首页 > 编程语言 > C语言/C++

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

2013-09-29 17:18 1056 查看
进行初步设计:

涉及的问题是:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐