我有一个模板类具有类型的数据成员std::vector<T>
其中T也是我的模板类的参数。
在我的模板类我有很长一段的逻辑,做这样的:
T &value = m_vector[index];
这似乎不是编译当T是一个布尔值,因为的std ::向量的[]操作不返回布尔参考,但是具有不同的类型。
一些替代品(虽然我不喜欢任何人):
- 告诉我的用户,他们不能使用布尔作为模板参数
- 有我的班布尔为专业化(但这需要一些代码重复)
难道没有办法告诉的std :: vector没有专门的布尔?
我有一个模板类具有类型的数据成员std::vector<T>
其中T也是我的模板类的参数。
在我的模板类我有很长一段的逻辑,做这样的:
T &value = m_vector[index];
这似乎不是编译当T是一个布尔值,因为的std ::向量的[]操作不返回布尔参考,但是具有不同的类型。
一些替代品(虽然我不喜欢任何人):
难道没有办法告诉的std :: vector没有专门的布尔?
你根本不可能有定期模板代码的行为进行T
等于bool
,如果你的数据被表示为std::vector<bool>
,因为这不是一个容器。 正如@马克赎金指出的那样,你可以使用std::vector<char>
代替,例如,通过这样的特质
template<typename T> struct vector_trait { typedef std::vector<T> type; };
template<> struct vector_trait<bool> { typedef std::vector<char> type; };
然后使用typename vector_trait<T>::type
无论当前使用std::vector<T>
这里的缺点是,你需要使用强制类型转换,从char
到bool
。
在你自己的答案提出一个替代方案是写与隐式转换和构造器的包装
template<typename T>
class wrapper
{
public:
wrapper() : value_(T()) {}
/* explicit */ wrapper(T const& t): value_(t) {}
/* explicit */ operator T() { return value_; }
private:
T value_;
};
并使用std::vector< wrapper<bool> >
到处而不必铸造。 然而,也有缺点,这是因为含有真实标准转换序列bool
参数行为不同于与所述用户定义的转换wrapper<bool>
(编译器可以至多使用1个用户定义的转换,并且尽可能多的标准转换为必要的) 。 这意味着,函数重载模板代码可以巧妙地打破。 你可以取消对explicit
关键字,在上面的代码,但一遍介绍的详细程度。
使用std::vector<char>
代替。
愿意为你下面的工作?
template <typename T>
struct anything_but_bool {
typedef T type;
};
template <>
struct anything_but_bool<bool> {
typedef char type;
};
template <typename T>
class your_class {
std::vector<typename anything_but_bool<T>::type> member;
};
少轻率,名字anything_but_bool
也许应该prevent_bool
或相似。
有防止一个方式vector<bool>
专业化:传递一个自定义的分配器。
std::vector<bool, myallocator> realbool;
下面的文章有一些细节: https://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=98
当然,这需要你有过控制vector
的定义,所以它可能不是真正适合你的解决方案。 除此之外,它也有它自己的一些缺点...
我发现一个更优雅的解决方案,根据您的所有投入。
首先,我定义了一个简单的类,拥有一个成员。 让我们把这种wrapperClass
:
template <typename T>
class wrapperClass
{
public:
wrapperClass() {}
wrapperClass(const T&value) : m_value(value) {}
T m_value;
};
现在我可以在这样的模板类定义我的std ::向量:
std::vector<wrapperClass<T>> m_internalVector;
由于sizeof(WrapperClass<bool>)
也为1,我期望sizeof(WrapperClass<T>)
将总是等于sizeof(T)
由于数据类型目前不是一个bool了,不进行专业化。
在地方,我现在得到的向量元素,我只需更换
m_internalVector[index]
通过
m_internalVector[index].m_value
但是,这似乎比使用性状的焦炭来代替布尔,然后使用强制转换为CHAR和布尔之间的转换更优雅(可能重新诠释转换到CHAR转换及到bool&)。
你怎么看?
你可以使用一个自定义代理类来保存的bool。
class Bool
{
public:
Bool() = default;
Bool(bool in) : value(in) {}
Bool& operator=(bool in) {value = in;}
operator bool() const& {return value;}
private:
bool value;
};
这可能需要一些调整你的目的,但它通常是我在这些情况下做的。