忽略模板特殊化并显式使用未特定化模板 (std::vector<bool>)
Ignore a template spezialization and explicitly use the unspezialized template (std::vector<bool>)
在处理一些旧代码时,它遇到了一个用于存储一些布尔值(在类构造函数中分配并用作数组)的std::unique_ptr<bool>
。
当我试图用std::vector<bool>
替换它时,我遇到了一个问题,因为我必须调用一个库函数,该函数需要一个计数和一个指向第一个布尔值(const bool*
)的指针:std::vector<bool>
有一个模板专用化,它将8个布尔值压缩为一个字节,因此如果不先解压缩数据,就不可能获得指向数据的bool*
指针。
我已经通过谷歌搜索或StackOverflow文章C++11 vector<bool>性能问题(代码示例),但它们都不适合我(即,使用包含布尔值的结构可以工作,但它使我试图简化的代码更加复杂;std::valarray
不提供数据()成员)
还有一篇文章"如何防止std::vector<bool>的专业化",但所有的解决方案都只有变通办法,我不相信"bool和无符号字符通常会占用相同的内存"这句话(在指向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;
}
答案是否定的,因为无法保证存在非专用模板。
特别是,编译器对所有内置类型进行专门化是非常合理的。因此,您通常会看到一个编译时调度:每当T
是内置类型时,vector<T>
就会转发到__VectorImplBuiltIn<T>
,而__VectorImplBuiltIn<T>
则专门用于每个单独的情况。因此,vector<float>
可以使用AVX一次复制4个浮点,并且vector<bool>
被打包。
现在没有可移植的方法来命名特定的实现类(它实际上是一个实现细节),而且未专用的__VectorImplBuiltIn<T>
甚至不会有通用实现,因为编译器供应商显然知道所有内置类型。
在这个方案中,"正常"的vector<T>
将扩展到__VectorImplClassType<T>
,这对于T==bool
来说可能是不可用的,因为bool
没有构造函数。
因此,一个完全合理的方案,其中std::vector<T>
从区分有构造函数和没有构造函数的类型开始,会让你的想法变得不可能。因此,ISO C++标准不允许你想要的东西也就不足为奇了。
您可以创建一个看起来与bool
行为相同的包装结构,因此不需要修改期望它是bool
:的代码
struct B {
bool val;
B() {}
B(bool val): val(val) {}
operator bool&() { return val; }
operator const bool&() const { return val; }
bool* operator&() { return &val; }
const bool* operator&() const { return &val; }
};
那么以下所有情况都是可能的:
B a = true, b(0);
a || 2 == 1;
5 ^ a;
const bool& x = a;
bool* y = &a;
a &= b;
!a;
这并不是你问题的确切答案,尽管它可能是你问题的答案。
你说你正在尝试使用一个以bool *
为参数的库,而你没有使用std::valarray
,因为它没有data()
。
但是下面的不起作用吗?
#include <iostream>
#include <valarray>
using namespace std;
void doStuff(bool *x) {
*x = true;
}
int main() {
valarray<bool> v = {false,false,false,false,false,false};
doStuff(&v[2]);
for (bool b : v) {
cout << b << endl;
}
//if you *really* want data(), &v[0] does the same
return 0;
}
实时演示
请注意,valarray保证具有连续内存。
另一种选择是创建一个替换容器,这里给出了一个名为SimpleVector
的示例,它只需要添加一个简单的头文件,代码的海报引用了Mark Allen Weiss的一本书。
在该实施方式中,CCD_ 25的行为与CCD_ 26相同。
尽管代码是c++11之前的代码,所以它没有实现&&
的构造函数。
- 使用std::vector的OpenCL矩阵乘法
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- std::vector的包装器,使数组的结构看起来像结构的数组
- 编译器如何区分std::vector的构造函数
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 在std::vector上存储带有模板的类实例
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 为什么std::vector比数组慢
- std::vector::迭代器是否可以合法地作为指针
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 为什么std::vector和std::valarray初始化构造函数不同
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 在没有未定义行为的情况下实现类似std::vector的容器
- 如何调整 std::vector of Eigen::MatrixXd 的大小
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 如何将AERT_Allocate与 std:vector 一起使用
- 推导 std::vector::back() 的返回类型
- 如何将原始字节附加到 std::vector?
- std::vector 没有重载函数的实例与参数列表匹配
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?