[英]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.