2010-09-26 79 views
3

我有什么办法可以简化下列语句吗? (可能使用boost::enable_ifC++ boost enable_if问题

我有一个简单的类结构 - Base基类,Derived1,Derived2继承自Base

我有以下代码:

template <typename Y> struct translator_between<Base, Y> { 
    typedef some_translator<Base, Y> type; 
}; 

template <typename Y> struct translator_between<Derived1, Y> { 
    typedef some_translator<Derived1, Y> type; 
}; 

template <typename Y> struct translator_between<Derived2, Y> { 
    typedef some_translator<Derived2, Y> type; 
}; 

我想写使用translator_between一个模板特相同的语句。

一个例子是什么我希望能够写(伪):

template <typename Class, typename Y> 

ONLY_INSTANTIATE_THIS_TEMPLATE_IF (Class is 'Base' or any derived from 'Base') 

struct translator_between<Class, Y> { 
    typedef some_translator<Class, Y> type; 
}; 

任何方式实现这一目标使用boost::enable_ifboost::is_base_of

回答

4

首先,你必须选择其中你的选择:

  • is_base_of
  • is_convertible

都可以是基金会d在<boost/type_traits.hpp>,后者更宽容。

如果你简单地防止这种类型的某种组合的实例,然后使用一个静态断言:

// C++03 
#include <boost/mpl/assert.hpp> 

template <typename From, typename To> 
struct translator_between 
{ 
    BOOST_MPL_ASSERT((boost::is_base_of<To,From>)); 
    typedef translator_selector<From,To> type; 
}; 

// C++0x 
template <typename From, typename To> 
struct translator_between 
{ 
    static_assert(boost::is_base_of<To,From>::value, 
       "From does not derive from To"); 
    typedef translator_selector<From,To> type; 
}; 

由于没有重载发生在这里,你不需要enable_if

4

我不认为boost::enable_if有帮助,因为SFINAE似乎宁愿在函数重载之间进行选择。与bool参数

当然你也可以使用模板来细化选择:

#include <boost/type_traits.hpp> 
class Base {}; 

class Derived : public Base {}; 

template <class A, class B> 
struct some_translator {}; 

template <typename A, typename B, bool value> 
struct translator_selector; //perhaps define type as needed 

template <typename A, typename B> 
struct translator_selector<A, B, true> 
{ 
    typedef some_translator<A, B> type; 
}; 

template <typename A, typename B> 
struct translator_between 
{ 
    typedef typename translator_selector<A, B, boost::is_base_of<Base, A>::value>::type type; 
}; 

int main() 
{ 
    translator_between<Base, int>::type a; 
    translator_between<Derived, int>::type b; 
    translator_between<float, int>::type c; //fails 
} 
0

您可以使用anable_if这里这个宏,使其更具可读性:

#define CLASS_REQUIRES(...) typename boost::enable_if<boost::mpl::and_<__VA_ARGS__, boost::mpl::bool_<true> > >::type 

然后,你可以定义你的类是这样的:

template <typename Class, typename Y, class Enable = 
CLASS_REQUIRES(boost::is_base_of<Class, Y>)> 
struct translator_between { 
    typedef some_translator<Class, Y> type; 
};