進行初步設計:
涉及的問題是:
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 更好:
template <typename T>class {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;
:保證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
// 缺點也很明顯: 比如涉及:1.0, FuncObj<float> , 1.0 預設的是double類型, 使用者沒有想把這些類都變成double類型,只是寫掉了一個f, 1.0f, 但編譯器不會報告錯誤
template <T1, T2>struct larger_type{typedef T1type;}template <>struct larger_type<float, double>{typedef doubletype;}