如何防止std :: vector <bool>的特化

Pat*_*ick 12 c++ templates boolean vector specialization

我有一个模板类,它有一个类型的数据成员std::vector<T>,其中T也是我的模板类的参数.

在我的模板类中,我有一些逻辑可以做到这一点:

T &value = m_vector[index];
Run Code Online (Sandbox Code Playgroud)

当T是布尔值时,这似乎不会编译,因为std :: vector的[]运算符不返回bool-reference,而是返回不同的类型.

一些替代方案(虽然我不喜欢其中任何一个):

  • 告诉我的用户他们不能使用bool作为模板参数
  • 我的班级专门为bool(但这需要一些代码重复)

有没有办法告诉std :: vector不专门为bool?

Tem*_*Rex 9

你根本无法经常有模板代码的行为为T等于bool如果你的数据被表示为std::vector<bool>,因为这不是一个容器.正如@Mark Ransom指出的那样,你可以使用std::vector<char>,例如通过这样的特征

template<typename T> struct vector_trait { typedef std::vector<T> type; };
template<> struct vector_trait<bool> { typedef std::vector<char> type; };
Run Code Online (Sandbox Code Playgroud)

然后typename vector_trait<T>::type在目前使用的任何地方使用std::vector<T>.这里的缺点是你需要使用强制转换来转换charbool.

您自己的答案中建议的另一种方法是使用隐式转换和构造函数编写包装器

template<typename T>
class wrapper
{
public:
        wrapper() : value_(T()) {}
        /* explicit */ wrapper(T const& t): value_(t) {}
        /* explicit */ operator T() { return value_; }
private:
        T value_;
};
Run Code Online (Sandbox Code Playgroud)

std::vector< wrapper<bool> >无需投射即可随处使用.但是,这也存在缺点,因为包含实际bool参数的标准转换序列的行为与用户定义的转换不同wrapper<bool>(编译器最多可以使用1个用户定义的转换,并根据需要使用多个标准转换).这意味着具有函数重载的模板代码可以巧妙地中断.您可以取消注释explicit上面代码中的关键字,但这会再次引入详细程度.