我正在处理无法更改数据类型的库。我需要调用一个使用bool
数组的函数。我正在使用的代码使用std::vector<bool>
来存储布尔值。我已经阅读了很多关于std::vector<bool>
以及SO相关问题的信息,但是我还没有找到解决我问题的最优雅的解决方案。这是性能至关重要的代码。如何以最有效的方式处理此问题?我可以更改存储在std::vector
中的类型,但不能逃避使用std::vector
的麻烦。
在我自己的问题中,我必须调用Fortran函数,但是我在C ++中做了一个最小的例子来说明问题。
#include <cstdio>
#include <vector>
void print_c_bool(bool* bool_array, size_t n)
{
for (int i=0; i<n; ++i)
printf("%d, %d\n", i, bool_array[i]);
}
int main()
{
// This works.
bool bool_array[5] = {true, false, false, true, false};
print_c_bool(bool_array, 5);
// This is impossible, but how to solve it?
std::vector<bool> bool_vector {true, false, false, true, false};
// print_c_bool(bool_vector.data(), bool_vector.size());
return 0;
}
答案 0 :(得分:5)
您知道该怎么做...创建临时布尔数组并复制值。
auto v = new bool[bool_vector.size()];
std::copy(bool_vector.begin(), bool_vector.end(), v);
print_c_bool(v, bool_vector.size());
delete[] v;
或
auto v = std::make_unique<bool>(bool_vector.size());
std::copy(bool_vector.begin(), bool_vector.end(), v.get());
print_c_bool(v.get(), bool_vector.size());
答案 1 :(得分:2)
我可以更改存储在
std::vector
中的类型,但是我无法转义 使用std::vector
。
在这种情况下,您很不走运。 std::vector<bool>
不存储布尔数组,其data()
也不返回指向布尔数组的指针(就像所有其他std::vectors
对其各自的数据类型一样)。
您可以玩一些技巧,并使用std::vector<uint8_t>
或类似的方法,即使大小匹配,uint8_t*
也不是bool*
!鉴于函数无法更改,您只能通过将数据复制到bool数组中来避免违反严格的别名。
如果您确实关心性能,那么我建议您考虑不使用std::vector<bool>
。例如,您真的需要动态尺寸吗?如果不使用std::array
。
答案 2 :(得分:0)
我尝试使用您的示例使其工作,并且以下(相当脏的)解决方案运行良好:
#include <iostream>
#include <vector>
void test_print(bool * arr, size_t s)
{
for(unsigned int i = 0; i< s; ++i)
std::cout << i << ": " << (arr[i]?"true\n":"false\n");
std::cout << std::endl;
}
int main()
{
bool b_arr[5] = {true, false, false, true, false};
test_print(b_arr, 5);
//std::vector <uint8_t> b_vec = {true, false, false, true, false}; // former proposal
std::vector <char> b_vec = {true, false, false, true, false}; // new proposal
test_print(reinterpret_cast<bool*>(b_vec.data()), b_vec.size());
return 0;
}
我得到的输出是:
0:正确
1:错误
2:错误
3:是的
4:错误
0:是的
1:错误
2:错误
3:是的
4:错误
但是,我不知道它在每个系统/平台上的表现是否都一样。但是,如果您不打算更改您的系统/平台,并且确实可以在您的系统/平台上运行,那么即使它是一个非常肮脏的解决方案,我也认为它可以完成这项工作。
事实上,如果我们可以保证sizeof(bool) == sizeof(uint8_t)
并假设true
和false
在内存中分别被视为整数1
和0
,解决方案将起作用,但不能成功。
我希望它能提供帮助。
编辑:用uint8_t
类型替换了char
。
EDIT2:
另一种不违反严格别名规则的解决方案是 Kamil Cuk 提到的一种解决方案,即创建一个Bool包装器并仍然检查sizeof(bool) == sizeof(Bool)
可能的实现方式(仅是基线代码)可以是:
struct Bool
{
bool v;
Bool(bool bv=false) : v(bv)
{}
};
然后您将能够编写:
std::vector<Bool> b_vec {true, false, false, true, false};
test_print(reinterpret_cast<bool*>(b_vec.data()), b_vec.size());
对我有用:)