如何$的std ::矢量&lt的对$ pvent专业化;布尔> [英] How to prevent specialization of std::vector<bool>

查看:114
本文介绍了如何$的std ::矢量&lt的对$ pvent专业化;布尔>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有了键入的std ::矢量&lt的数据成员的模板类; T> ,其中T是也是我的模板类的参数。

在我的模板类我有很长一段的逻辑,做这样的:

  T&放大器;值= m_vector [指数]

这似乎并没有编译当T是一个布尔值,因为的std ::向量的[]操作符不返回布尔参考,但不同的类型。

一些替代品(虽然我不喜欢其中的任何):


  • 告诉我的用户,他们不得使用布尔作为模板参数

  • 有我的班布尔为专业化(但这需要一些code复制)

难道没有办法告诉的std :: vector没有专门的布尔?


解决方案

您根本不可能有模板code定期表现为 T 等于布尔如果您的数据重新通过的std ::矢量<&布尔GT; ,因为这不是一个容器。正如@马克赎金指出的那样,你可以使用的std ::矢量<&字符GT; 代替,例如通过这样的特征

 模板< typename的T>结构vector_trait {的typedef的std ::矢量< T>类型; };
模板<>结构vector_trait<布尔> {的typedef的std ::矢量<&烧焦GT;类型; };

然后用类型名称vector_trait< T> ::类型无论你currrently使用的std ::矢量< T> 。这里的缺点是,你需要使用强制类型转换,从字符转换为布尔

在你自己的雁建议的替代方法是写与隐式转换和构造

包装

 模板< typename的T>
类包装
{
上市:
        包装():VALUE_(T()){}
        / * *明确/封装(T&常量amp; T公司):VALUE_(T){}
        / * *明确/运营商T(){返回VALUE_; }
私人的:
        ŤVALUE_;
};

和使用的std ::矢量<包装<布尔> > 无处不在而不必强制转换。然而,也有缺点,这是因为含有真正的布尔参数标准转换序列不同的表现比包装&LT用户定义的转换;布尔> (编译器可以最多使用1用户自定义的转换,并尽可能多的标准转换为必要)。这意味着模板code。与函数重载可以巧妙地打破。你可以取消注释明确中的关键字code以上,但一遍介绍的详细程度。

I have a templated class that has a data member of type std::vector<T>, where T is also a parameter of my templated class.

In my template class I have quite some logic that does this:

T &value = m_vector[index];

This doesn't seem to compile when T is a boolean, because the [] operator of std::vector does not return a bool-reference, but a different type.

Some alternatives (although I don't like any of them):

  • tell my users that they must not use bool as template parameter
  • have a specialization of my class for bool (but this requires some code duplication)

Isn't there a way to tell std::vector not to specialize for bool?

解决方案

You simply cannot have templated code behave regularly for T equal to bool if your data is represented by std::vector<bool> because this is not a container. As pointed out by @Mark Ransom, you could use std::vector<char> instead, e.g. through a trait like this

template<typename T> struct vector_trait { typedef std::vector<T> type; };
template<> struct vector_trait<bool> { typedef std::vector<char> type; };

and then use typename vector_trait<T>::type wherever you currrently use std::vector<T>. The disadvantage here is that you need to use casts to convert from char to bool.

An alternative as suggested in your own anser is to write a wrapper with implicit conversion and constructor

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

and use std::vector< wrapper<bool> > everywhere without ever having to cast. However, there are also disadvantages to this because standard conversion sequences containing real bool parameters behave differently than the user-defined conversions with wrapper<bool> (the compiler can at most use 1 user-defined conversion, and as many standard conversions as necessary). This means that template code with function overloading can subtly break. You could uncomment the explicit keywords in the code above but that introduces the verbosity again.

这篇关于如何$的std ::矢量&lt的对$ pvent专业化;布尔&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆