【问题标题】:Odd Template behaviour when T == boolT == bool 时的奇怪模板行为
【发布时间】:2015-05-22 01:23:18
【问题描述】:

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

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

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

编译器错误:

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)

为什么会这样?

【问题讨论】:

  • “数组”是 std::vector 吗? (如果是这样, std::vector 是特殊的)
  • 是的。它有什么特别之处?
  • This is。如果您的意思是std::vector,请不要说数组。
  • 下次请提供一个最小的完整测试用例。它避免了这样的问题,即您遗漏了关键细节而没有意识到它们是至关重要的。
  • 你有一个类模板来存储任意类型的数组T,并且你有一个成员函数getBool,无论Tbool,它都将reinterpret_cast ?!似乎是一个很棒的主意。

标签: c++ templates


【解决方案1】:

std::vector&lt;T&gt; 的通用实现不同,std::vector&lt;bool&gt; 在很多时候是一种专门化,它的实现使得std::vector&lt;boo&gt;::operator[](size_t) 返回一个bool,而不是bool&amp;

因此,

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

【讨论】:

  • 有趣。有没有其他奇怪的向量类型案例?
  • @newObjekt, vector&lt;bool&gt; 是我所知道的唯一一个。
【解决方案2】:

values 是一个std::vector&lt;bool&gt;,即a special version of vector,它将布尔值打包成位。

values[i] 的结果是一个特殊的proxy 类(或者只是bool 的副本,如果向量是const),它的作用类似于对布尔值的引用,但不幸的是它不是真实的参考。错误信息所指的“临时”就是这个代理类。

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

【讨论】:

    猜你喜欢
    • 2016-11-18
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    相关资源
    最近更新 更多