我有一个模板类,它有一个std::vector<T>
类型的数据成员,其中T也是我的模板类的一个参数。
在我的模板类中,我有相当多的逻辑可以做到这一点:
T &value = m_vector[index];
当T是一个布尔值时,这似乎无法编译,因为std::vector的[]操作符没有返回一个布尔值引用,而是返回一个不同的类型。
一些替代品(虽然我不喜欢他们中的任何一个):
- 告诉我的用户他们不能使用bool作为模板参数
- 我专门为bool定义了我的类(但这需要一些代码重复)
有没有办法告诉std::vector不要专门处理bool?
7条答案
按热度按时间alen0pnh1#
如果你的数据是用
std::vector<bool>
表示的,那么你就不能让模板化的代码在T
等于bool
的情况下正常工作,因为这不是一个容器。然后在当前使用
std::vector<T>
的地方使用typename vector_trait<T>::type
。这里的缺点是需要使用强制转换从char
转换为bool
。您自己的答案中建议的另一种方法是编写一个具有隐式转换和构造函数的 Package 器
并且在任何地方都使用
std::vector< wrapper<bool> >
,而不必强制转换。但是,这样做也有缺点,因为包含实bool
参数的标准转换序列的行为与使用wrapper<bool>
的用户定义转换不同(编译器最多可以使用1个用户定义转换,和尽可能多的标准转换)。这意味着带有函数重载的模板代码可能会微妙地中断。您可以取消注解上面代码中的explicit
关键字,但这又会引入冗长。9jyewag02#
请改用
std::vector<char>
。polkgigr3#
下面的方法对你有用吗?
不那么轻率的是,名称
anything_but_bool
可能应该是prevent_bool
或类似的名称。mrwjdhj34#
我发现了一个更优雅的解决方案,基于你所有的输入。
首先我定义了一个简单的类,它包含一个成员,我们将其命名为
wrapperClass
:现在我可以在我的模板类中定义我的std::vector,如下所示:
因为
sizeof(WrapperClass<bool>)
也是1,所以我希望sizeof(WrapperClass<T>)
总是等于sizeof(T)
,因为数据类型现在不再是bool,所以不执行专门化。在从向量中得到元素的地方,我只需要替换
作者
但这似乎比使用traits用char替换bool,然后使用cast在char和bool之间转换(可能还会重新解释cast以将char &转换为bool &)优雅得多。
你觉得呢?
hwamh0ep5#
您可以使用自定义代理类来保存布尔值。
为了您的目的,这可能需要一些调整,但这通常是我在这些情况下所做的。
xxslljrj6#
从语义上讲,使用
string
很奇怪,但它的工作原理基本上与std::vector
类似,其指针/引用的行为与预期一致,并且在传递给接受span的函数时,它可以方便地转换为std::span<bool>
。不需要 Package 类或reinterpret_cast(例如,使用std::vector<uint8_t>
会因为强制类型转换而使这些情况很尴尬).除非C++添加std::bit_vector
并弃用专门化,否则我们没有太多好的选择.hwamh0ep7#
有一种方法可以防止
vector<bool>
专门化:传递自定义分配器。下面的文章有一些细节:https://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=98
当然,这需要您能够控制
vector
的定义,因此它可能并不适合您。除此之外,它也有自己的一些缺点...