2016-08-19 82 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) –