当T == bool时,奇怪的模板行为

时间:2015-05-21 17:09:09

标签: c++ templates

我真的不知道如何描述这个问题,但我有一个模板类,它存储一个值数组并将其转换为各种数据类型。一般来说,我不会将一个布尔值转换为浮点数,但由于模板的工作方式,它必须实现。

这会导致一个奇怪的问题,当T [] = bool []时,我在这段代码上出错:

virtual bool getBool(uint i) {
 bool b;
 b = *reinterpret_cast<bool*>(&values[i]);
 return b;
}

Compliler错误:

error: taking address of temporary

但这可以编译并正常工作:

 virtual bool getBool(uint i) {
  bool b;
  T c = values[i];
  b = *reinterpret_cast<bool*>(&c);
  return b;
 }

这两段代码的工作方式完全相同,但是当T是bool时,第一段代码不能编译。 int,float和std :: string按此方式使用此代码的两个版本。 (gcc c ++ 11)

为什么会这样?

2 个答案:

答案 0 :(得分:1)

std::vector<T>的通用实现不同,std::vector<bool>很多时候都会实现专门化,std::vector<boo>::operator[](size_t)会返回bool,而不是bool&

因此,

std::vector<bool> v{0, 1};
v[0]; // Returns an object
bool* ptr = &v[0]; // Not allowed since v[0] returns an object
                   // by value.

然而,

bool b = v[0];
bool* ptr = &b; // OK since you are taking address of b.

可以在http://en.cppreference.com/w/cpp/container/vector_bool找到更多信息。

答案 1 :(得分:1)

valuesstd::vector<bool>a special version of vector将bool打包成位。

values[i]的结果是一个特殊的proxy类(或者只是bool的副本,如果向量是const),它的作用就像是对{ bool,但遗憾的是不是真正的参考。错误消息引用的“临时”是此代理类。

另请参阅:Why vector<bool>::reference doesn't return reference to bool?this article