2016-08-19 83 views
1

我想問你最近幾天我遇到的編程頭痛的幫助。讓我試着解釋我即將實施的內容...函子運算符的條件特化()

我的目標是定義一組有效的等式。讓我更詳細地解釋...

我認爲是每個方程對象的仿函數 - 定義operator()的類。該運算符的定義應該針對每個方程類型專門定義。專業化包含計算本身:

.H:

enum class IDs : int { A = 0, B = 1, C = 2 }; 

template<IDs WHICH> 
struct Equation 
{ 
    int operator() (void); 
} 

的.cpp:

template<> 
Equation<IDs::A>::operator()(void) 
{ 
    /* Just some sample equation */ 
    return(42 + 28); 
} 

正如你可能已經注意到,專業化是通過枚舉類成員ID ::定義。

這似乎是工作。但我想添加所謂的可用性功能 - 該方程式可能僅對某些用戶對象類型有效。

There is 'validity group' declared: 
/* Object types declaration */ 
namespace Objects { 
    using Object0 = boost::mpl::int_<0>; 
    using Object1 = boost::mpl::int_<1>; 
    using Object2 = boost::mpl::int_<2>; 
} 
/* Validity groups declaration */ 
using ValidityGroup1 = boost::mpl::vector<Object0, Object2>; 
using ValidityGroup2 = boost::mpl::vector<Object1>; 

我正在使用以下結構來使類或禁用(使用boost :: enable_if)。只是爲了顯示我如何使用它:

template<typename TYPE_LIST, typename QUERY_TYPE> 
struct IsTypeInList 
{ 
    using TypePos = typename boost::mpl::find<TYPE_LIST, QUERY_TYPE>::type; 
    using Finish  = typename boost::mpl::end<TYPE_LIST>::type; 
    using type  = typename boost::mpl::not_<boost::is_same<TypePos, Finish> >::type; 
    using value_type = typename type::value_type; 

    static const bool value = type::value; 
}; 

template<typename OBJECT_TYPE, typename ENABLER=void> 
class SampleClass; 

template<typename OBJECT_TYPE> 
class SampleClass<OBJECT_TYPE, typename boost::enable_if<typename IsTypeInList<ValidityGroup1, Object0>::type>::type> 
{} 

SampleClass的部分特僅當Object0屬於ValidityGroup1。到現在爲止還挺好。這個原則已經過驗證。

現在有趣的東西來了。我想這兩個東西融合在一起:

目標:

定義公式的運算符()誰是包含有效的身體專業化是通過標識::定義?枚舉類值「,並且只對屬於ValidityGroup的對象可用...可以有另一個相同的ID :: ??計算,但對其他ValidityGroup中的Object有效(也稱爲Object0的屬性,而不是Object1的其他計算方法)

我知道整個概念是相當複雜的,可能會造成混亂讓我告訴我的努力來實現這個東西。

template<typename OBJECT_TYPE, typename VALIDITY_GROUP, IDs ID, typename ENABLER = void> 
class Equation; 

template<typename OBJECT_TYPE, typename VALIDITY_GROUP, IDs ID> 
class Equation<OBJECT_TYPE, VALIDITY_GROUP, ID, typename boost::enable_if<typename IsTypeInList<VALIDITY_GROUP, OBJECT_TYPE>::type>::type > 
: public EquationBase<IDs> 
{ 
public: 
int operator() (void); 
}; 

template<typename OBJECT_TYPE, typename VALIDITY_GROUP, IDs ID> 
int Equation<OBJECT_TYPE, ValidityGroup1, Ids::A>::operator() (void) 
{ 
    return(42 + 56); 
} 

但是運營商()的定義是不工作...你能請指教我怎麼做這個工作?或者沒有人有任何其他想法如何實現上述目標?

非常感謝提前向任何人願意幫我...

乾杯馬丁

編輯: 方程式模板類對象使用。讓代碼解釋:

template<typename OBJECT_TYPE> 
class Object 
{ 
public: 
    Object(void); 
}; 

的.cpp:

template<typename OBJECT_TYPE> 
Object<OBJECT_TYPE>::Object(void) 
{ 
    std::cout << Equation<IDs::A>()() << std::endl; 
} 

問題是,當運營商()是專門OBJECT_TYPE沒有定義...

回答

1

如果我正確你想了解什麼爲了獲得,我想有很多方法。

以下是IPER-semplified例如(但完整的廣告工作),說明如何使用std::enable_if(但boost::enable_if應該OK)與返回類型的操作的

#include <iostream> 
#include <type_traits> 

template <typename ObjT, typename ValT> 
class Equation 
{ 
    public: 
     template <typename X = ObjT> 
     typename std::enable_if<true == std::is_same<X, ValT>::value, int>::type 
     operator() (void) 
      { return(0); } 

     template <typename X = ObjT> 
     typename std::enable_if<false == std::is_same<X, ValT>::value, int>::type 
     operator() (void) 
      { return(1); } 
}; 

int main() 
{ 
    Equation<int, int> eq0; 
    Equation<int, long> eq1; 

    std::cout << "eq0 val: " << eq0() << std::endl; // print "eq0 val: 0" 
    std::cout << "eq1 val: " << eq1() << std::endl; // print "eq1 val: 1" 
} 

不是真的來選擇不同的實現優雅,我想。

另一種解決方案(即,我想,最適合您的必要條件),可能是以下基於類偏特

#include <iostream> 
#include <type_traits> 


template <typename ObjT, typename ValT, bool = std::is_same<ObjT, ValT>::value> 
class Equation; 

template <typename ObjT, typename ValT> 
class Equation<ObjT, ValT, true> 
{ 
    public: 
     int operator()(); 
}; 

template <typename ObjT, typename ValT> 
class Equation<ObjT, ValT, false> 
{ 
    public: 
     int operator()(); 
}; 


template <typename ObjT, typename ValT> 
int Equation<ObjT, ValT, true>::operator()() 
{ return(0); } 

template <typename ObjT, typename ValT> 
int Equation<ObjT, ValT, false>::operator()() 
{ return(1); } 

int main() 
{ 
    Equation<int, int> eq0; 
    Equation<int, long> eq1; 

    std::cout << "eq0 val: " << eq0() << std::endl; // print "eq0 val: 0" 
    std::cout << "eq1 val: " << eq1() << std::endl; // print "eq1 val: 1" 
} 
+0

非常感謝Max66!我會等待:o)期待看看。也許還有一件事需要考慮......方程式由一個也是模板化的類擁有,根據所有者對象模板參數選擇適當的operator()實現將是非常好的...請參閱我的原始文章中的編輯... –

+0

@MartinKopecký - 增加了另一個例子;對不起,但你「類似於:」是你評論的最後一部分;我不明白你想要什麼;我認爲如果你修改這個問題或者(如果你的下一個需求是真的不同),插入另一個問題會更好 – max66

+0

對不起,我編輯原始文章的速度很慢......非常感謝你的努力,我會分析你的代碼,適合...我已經嘗試了這麼多的變體,所以我現在對我的主題感到有點困惑...... o) –