繁体   English   中英

编写通用包装:有条件地将模板参数中的不同类型映射到单个类内部类型

[英]Writing a Generic Wrapper: Conditionally Map different Types from Template Arguments onto a Single Class-Internal Type

TL; DR:如何根据模板参数的类型执行条件typedef。

我正在为不同的位集实现编写包装器。 为此,我引用std::bitset<>boost::dynamic_bitset<> 我观察到boost::dynamic_bitset<>如下实施std::bitset<>例如通过呼吁指数代理类通过处理返回operator[]有一类称为reference ,就像std::bitset<>一样。 因此,这很有用,因为在我的包装器中(以位集类型BITSET为模板),然后我可以

typename BITSET::reference operator[](INDEX_TYPE i)
    { return bitset[i]; }

它对std::bitset<>boost::dynamic_bitset<>

但是,有些功能无法像这样并行化。 例如声明boost::dynamic_bitset<> typedef std::size_t size_type; 作为索引类型,如:

bool operator[](size_type pos) const { return test(pos); }

但是std::bitset<>只是使用size_t

_GLIBCXX_CONSTEXPR bool                                                                          
operator[](size_t __position) const
{ return _Unchecked_test(__position); }

因此,在我的包装程序中,我可以执行typedef size_t INDEX_TYPE或类似的操作,但是这对于另一个不使用size_t实现可能不起作用,因为这两个巧合(或不巧合)。

显然,没有真正通用的方法可以执行此操作,但是至少可以通过某种方式有条件地定义我的INDEX_TYPE ,类似于:

template <class BITSET, class T>
/**
 *
 * @tparam T Use this parameter to pass on the template parameter that
 *         was used to template BITSET
 */
class BitsetWrapper
{
public: // typedefs
    if (typeid(BITSET) == bool::dynamic_bitset<T>)
        typedef tyeanme BITSET::size_type INDEX_TYPE;
    else if (typeid(BITSET) == std::bitset<T>)
        typedef size_t INDEX_TYPE;
    else if (typeid(BITSET) == BitSet<T>) // my own implementation
        typedef BITSET::INDEX_TYPE INDEX_TYPE;
    else
        throw std::invalid_argument("unsupported type: "+typeid(BITSET).name());

上面的方法行不通,即使看起来很笨拙。

这不是我的问题的重点,但是出于完整性考虑,这就是错误:

bitsetWrapper.hpp:34:5: error: expected member name or ';' after declaration specifiers
    if (typeid(BITSET) == bool::dynamic_bitset<T>)
    ^
bitsetWrapper.hpp:36:5: error: expected member name or ';' after declaration specifiers
    else if (typeid(BITSET) == std::bitset<T>)
    ^
bitsetWrapper.hpp:38:5: error: expected member name or ';' after declaration specifiers
    else if (typeid(BITSET) == BitSet<T>)
    ^
bitsetWrapper.hpp:40:5: error: expected member name or ';' after declaration specifiers
    else

我想您不能只是将条件随机地放到函数外部的类空间中,并且这是我第一次尝试这样做,因为情况很怪异。

但是,如何才能正确地解决呢?

您不能使用if/else逻辑来定义这样的typedef 您可以使用助手类来推断它。

template <typename T> struct TypedefSelector;

template <typename T> struct TypedefSelector<boost::dynamic_bitset<T>>
{
   using IndexType = BITSET::size_type;
};

template <typename T> struct TypedefSelector<std::bitset<T>>
{
   using IndexType = size_t;
};

template <typename T> struct TypedefSelector<BitSet<T>>
{
   using IndexType = BITSET::INDEX_TYPE;
};

然后使用:

template <class BITSET, class T>
class BitsetWrapper
{
   using INDEX_TYPE = typename TypedefSelector<T>::IndexType;
   ...
};

对于没有TypedefSelector ,您将得到编译时错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM