编写泛型包装器:有条件地将模板参数中的不同类型映射到单个类内部类型
Writing a Generic Wrapper: Conditionally Map different Types from Template Arguments onto a Single Class-Internal Type
TL;DR:如何根据模板实参的类型执行条件类型定义
我正在为不同的bitset实现编写包装器。我引用了std::bitset<>
和boost::dynamic_bitset<>
。我观察到boost::dynamic_bitset<>
遵循std::bitset<>
的实现,例如通过调用代理类来处理由operator[]
返回的索引处理,类称为reference
,就像std::bitset<>
一样。这很有用,因为在我的包装器中——它是用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
的类型名,将得到编译时错误。
- 将类型映射到整数值后,如何在给定整数值的情况下恢复类型?
- C++17:在编译时将类型映射到整数值
- 为C++重载函数创建SWIG类型映射
- 返回各种类型的函数的SWIG类型映射
- 类型映射资源并将列表转换为矢量(并返回)
- 有没有办法在 C++17 中创建编译时类型映射以进行类型检查?
- 如何在OpenCV中使用双类型映射进行重新映射
- SWIG 多参数类型映射适用于函数,但如果有多个构造函数,则不适用于构造函数
- Swig:如何类型映射c ++字符串常量和python字符串?
- SWIG 类型映射的 python 列表到双倍 *
- SWIG -- 在扩展中使用类型映射
- 嵌入的多个变体类型映射
- SWIG类型映射中的内存释放
- 您将如何为 std::list<std::string> 创建一个类型映射,以在<String> List in C++ 中为 Java 在 SWIG 中创建?
- SWIG-为具有四个参数的函数创建一个类型映射,该参数传递一个字节数组
- 在C++中将类类型映射到其他类类型
- C func 到C++具有非双射参数类型映射的实例成员蹦床
- Swig 界面中的类型映射错误
- 如何在 swig 中引用类型映射类
- 将实例变量类型映射到模板成员函数