c++ - 忽略模板特化并显式使用非特化模板 (std::vector<bool>)

标签 c++ templates pointers c++11 vector

在处理一些旧代码时遇到了 std::unique_ptr<bool>用于存储一些 bool 值(在类构造函数中分配并用作数组)。

当我尝试用 std::vector<bool> 替换它时当我不得不调用一个库函数时遇到了一个问题,该函数接受一个计数和一个指向第一个 bool 值(const bool*)的指针:std::vector<bool> 有一个模板特化。它将 8 个 bool 值压缩为一个字节,因此不可能得到 bool*指向数据的指针而不先解压缩它。

我已经通过谷歌搜索或 StackOverflow 文章找到了一些解决方案 C++11 vector<bool> performance issue (with code example)但它们都不适合我(即使用包含 bool 值的结构会起作用,但它使我尝试简化的代码更加复杂;std::valarray 不提供 data() 成员)

还有一篇文章“How to prevent specialization of std::vector<bool>”,但所有解决方案都只是解决方法,我不相信“bool 和 unsigned char 通常自行占用相同数量的内存”这句话(在 compiler error when pointing to an element of std::vector<bool>? 中提到) )

我还检查了Alternative to vector<bool>但是我们在我们的解决方案中不使用 boost,我不愿意为单次使用添加这种依赖。

我的问题是:有没有一种方法可以忽略模板特化并为类型显式使用非特化模板?

例如

#include <iostream>

template<class T>
class MyTemplate
{
public:
  static const int Value = 0;
}

template<>
class MyTemplate<double>
{
public: 
  static const int Value = 1;
};

int main(int argc, char **argv)
{
  // How can I make MyTemplate<double> ignore the spezialization and output 0?
  std::cout << "0==" << MyTemplate<double>::Value << std::endl;

  return 0;
}

最佳答案

答案是否定的,因为无法保证非特化模板的存在。

特别是,编译器对所有内置类型进行专门化是很合理的。所以你通常会看到一个编译时分派(dispatch):vector<T>转发到 __VectorImplBuiltIn<T>每当T是内置类型,__VectorImplBuiltIn<T>反过来专门针对每个个案。所以vector<float>可以使用 AVX 一次复制 4 个 float ,并且 vector<bool>包装好。

现在没有可移植的方式来命名特定的实现类(它实际上是一个实现细节)和非特化的 __VectorImplBuiltIn<T>甚至没有通用实现,因为编译器供应商显然知道所有内置类型。

在这个方案中,“正常”vector<T>将扩展为 __VectorImplClassType<T> ,这对于 T==bool 可能是不可用的因为bool没有构造函数。

这是一个非常合理的方案,其中std::vector<T>从区分有和没有构造函数的类型开始会让你的想法变得不可能。因此,ISO C++ 标准不允许您想要的也就不足为奇了。

关于c++ - 忽略模板特化并显式使用非特化模板 (std::vector<bool>),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37477445/

相关文章:

c++ - 创建动态分配的数组

c++ - 如何创建模板依赖成员类型

c++ - 实现 C++ 模板列表类的高效初始化

c++ - 从 Typelist 子集创建函数指针

c - C语言中如何通过指针传递二维数组?

C++查找USB设备挂载点

c++ - 什么是对象切片?

c++ - 将存储在 int64_t 中的系统时钟(微秒)转换为 float ?

c++ - void* 和 void * 有什么区别

C malloc 字符串