-2

I don't really know how to describe this problem but I have a template class that stores an array of value and casts it out to various data types. Generally I'm not going to cast a boolean to a float but it has to be implemented because of the way the templates work.

This causes a weird issue where when T[] = bool[] I get an error on this code:

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

Compliler error:

error: taking address of temporary

But this compiles and works fine:

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

These two pieces of code work exactly the same but the first will not compile when T is bool. int, float, and std::string work as intended with both versions of this code. (gcc c++11)

Why does this happen?

new Objekt
  • 414
  • 3
  • 8
  • Is the 'array' a std::vector? (if so, std::vector is special) –  May 21 '15 at 17:13
  • Yeah it is. What's special about it? – new Objekt May 21 '15 at 17:16
  • http://stackoverflow.com/q/30376032/560648 just a few hours ago! – Lightness Races in Orbit May 21 '15 at 17:17
  • 3
    [This is](http://en.cppreference.com/w/cpp/container/vector_bool). Don't say array if you mean `std::vector`. – Useless May 21 '15 at 17:17
  • 1
    Next time present a minimal, _complete_ testcase please. It avoids issues like this, where you leave out crucial details not realising that they're crucial. – Lightness Races in Orbit May 21 '15 at 17:18
  • 2
    You have a class template that stores an array of any arbitrary type `T`, and you have a member function `getBool` that'll `reinterpret_cast` whatever `T` is into a `bool`?! Seems like an awesome idea. – Praetorian May 21 '15 at 17:18
  • @Praetorian There are catches for invalid casts and special cases for bool to string being changed to "true" and "false". I just wanted learn about this weird case. If there are better ways to do stuff like this I want to learn. Being condescending/sarcastic is not constructive at all. – new Objekt May 21 '15 at 17:29

2 Answers2

1

Unlike the generic implementation of std::vector<T>, std::vector<bool> is many times a specialization that is implemented such that std::vector<boo>::operator[](size_t) returns a bool, not a bool&.

Hence,

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.

However,

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

More informaton can be found at http://en.cppreference.com/w/cpp/container/vector_bool.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

values is a std::vector<bool>, which is a special version of vector that packs the bools into bits.

The result of values[i] is a special proxy class (or simply a copy of the bool, if the vector is const) that acts like a reference to a bool, but is unfortunately not a real reference. The "temporary" referred to by the error message is this proxy class.

See also: Why vector<bool>::reference doesn't return reference to bool? and this article.

Community
  • 1
  • 1
Apples
  • 3,135
  • 1
  • 21
  • 26