2014-06-27 74 views
4

我對C++(使用C++ 2011)相當陌生,我想爲以下問題找到解決方案。我有一個表示fonction一類:模板參數簡化

class Curve { 
private: 
    ... 
public: 
    std::array<double, 3> value(double s); 
} 

我使用的對象給此函數傳遞到由一類爲代表的算法:

template <int n, typename Functor> 
class Algorithm { 
private: 
    Functor f; 
    std::array<double, n> a; 
public: 
    ... 
} 

然後我創建對象

Algorithm<3, Curve> solver; 

但是3很明顯是來自任何類型曲線對象的方法值返回數組大小的3。我想簡化該代碼,以便我可以使用:

Algorithm<Curve> solver; 

但我對如何做到這一點不知道。你介意給我一個提示嗎?

最好的問候, 弗朗索瓦

+0

看一看的std ::向量。它們與許多其他編程語言的列表相媲美。 – Nallath

+1

@Nallath不,大小在編譯時已知。 'std :: array'是最好的選擇。 – Manu343726

+0

我非常喜歡優化事物(例如:保持模塊化)。但那可能是個人風格的事情。 – Nallath

回答

8

添加成員array_length或類似Curve像類的東西:

class Curve 
{ 
public: 
    static constexpr const std::size_t length = 3; 

private: 
    std::array<double,length> a; 
}; 

template<typename ALGORITHM , std::size_t n = ALGORITHM::length> 
class Algorithm 
{ 
    ... 
}; 

如果你需要讓經典的功能實體的算法,這種做法行不通因爲沒有length成員。其他方式可能是建立一個元函數data_length 這賦予了算法函數F返回數據的長度:

template<typename F> 
struct length; 

//Specialization for Curve class: 
template<> 
struct length<Curve> : public std::integral_constant<std::size_t,3> 
{}; 

然後:

template<typename F , std::size_t n = length<F>::value> 
struct Algorithm 
{ 
    ... 
}; 

編輯:像任何其他模板,執行該方法指定其模板參數:

template<typename F , std::size_t N> 
void Algorithm<F,N>::execute() 
{ 
    _f(); 
} 

Here是一個運行的例子。

+0

感謝Manu,但是我不能讓它工作,因爲我不知道如何實現算法的方法。我試過了:template 算法 ::方法(....)。但它不起作用。我已經嘗試了其他一些東西,但它不起作用。 – InsideLoop

+0

@InsideLoop在幾分鐘內看到編輯 – Manu343726

+0

@InsideLoop準備就緒。 – Manu343726

1

你可以在枚舉成員的「通行證」 3是這樣的:

class Curve { 
public: 
    enum { arity = 3 }; 
    std::array<double, arity> value(double s); 
}; 

template <typename Functor> 
class Algorithm { 
private: 
    std::array<double, Functor::arity> a; 
}; 

Curve curve; 
Algorithm<Curve> solver; 
1

使用decltype得到的value的返回類型,std::tuple_size找出它有多大(Live at Coliru):

template <typename Functor> 
class Algorithm { 
private: 
    Functor f; 
    static const std::size_t n = 
     std::tuple_size<decltype(f.value(0.))>::value; 
    std::array<double, n> a; 
public: 
    // ... 
}; 

or if you simply want a to have the same type that value returns

template <typename Functor> 
class Algorithm { 
private: 
    Functor f; 
    decltype(f.value(0.)) a; 
public: 
    // ... 
}; 

,或者如果你有一天會需要使用不同類型的功能 - 表示intlong long或任何 - you can ask for the return type of f.value when invoked with a default-constructed value of whatever its argument type happens to be

template <typename Functor> 
class Algorithm { 
private: 
    Functor f; 
    decltype(f.value({})) a; 
public: 
    // ... 
}; 
+0

這是另一個非常不錯的選項,使Functor的實現更容易。 – InsideLoop