0

Question was changed!

I use a simple way to hide my enums from local namespaces - enumeration inside of a struct. It goes roughly like this:

struct Color
{
    enum Type
    {
        Red, Green, Black
    };
    Type t_;
    Color(Type t) : t_(t) {}
    operator Type () const {return t_;}
private:
  template<typename T>
  operator T () const;
};

operator T () is a protection from implicit type casting. Then I tried to compile this code with gcc and with keil:

Color n;
int a[9];
a[ (int)n ] = 1;

gcc compiled it with no error (wich is what I expected), but Keil gived me an error: "invalid type conversion. operator () is inaccessible".

So my question is: which compiler is right?

I know about c++11 enum class, but it isn't supported by Keil now

Amomum
  • 6,217
  • 8
  • 34
  • 62
  • 2
    Neither g++ nor clang++ compile this code for me, even after having fixed the definition of `Color n;`. – Mat May 21 '13 at 13:36
  • What version of g++ are you using? What are the errors? – Amomum May 21 '13 at 13:39
  • `invalid cast from type ‘Color’ to type ‘int’`: GCC 4.6.3, 4.7.2, 4.8.0; `reinterpret_cast from 'Color' to 'int' is not allowed`: clang 3.3 – Mat May 21 '13 at 13:42
  • Now that's interesting. I actually use this thing with a macro and it did compile. But I tried this simple snippet and it didn't. I'm confused. UPD: Right, c-style casting works in g++, but doesn't in Keil. I should test code before question it :( The question should be about C-style conversion – Amomum May 21 '13 at 13:49
  • I'm not sure if this has anything to do with it but on http://stackoverflow.com/questions/573294/when-to-use-reinterpret-cast I found this comment, "in C++03 a cast of ```int*``` to ```void*``` was forbidden to be done with reinterpret_cast (although compilers did not implement that and it was impractical, hence was changed for C++11)". Since structs involve pointers to the object. Maybe the reason why Keil doesn't like it is due to that C++03 standard. – Travis Pessetto May 21 '13 at 13:55
  • But there is no pointers here.. – Amomum May 21 '13 at 13:56
  • There is no such thing as an implicit type cast. A **cast** is something you write in your source code to tell the compiler to do a **conversion**. Some conversions require a cast; these are **explicit** conversions. Some don't; these are **implicit** conversions. – Pete Becker May 21 '13 at 14:52
  • Sorry, I'm not a native speaker, I thought cast is a synonym to type conversion. – Amomum May 21 '13 at 15:35

1 Answers1

4

Should reinterpret_cast (not c-style () cast) call type conversion operator?

No, reinterpret_cast is only used for a few dodgy types of conversions:

  • converting pointers to integers and back
  • converting between pointers (and references) to unrelated types

You shouldn't need a cast at all to use the implicit conversion operator - you have not prevented implicit conversion at all. In C++11, if the operator were explicit, then you'd need a static_cast.

If you're stuck with C++03, and you really want to prevent implicit conversion but allow explicit conversion, then I think the only sensible thing to do is to provide a named conversion function.

Update: The question has now changed, and is asking about C-style casting rather than reinterpret_cast. That should compile since any conversion that can be done by static_cast (including implicit conversions) can also be done with a C-style cast.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • So making operator private doesn't make implicit conversion impossible? o_o – Amomum May 21 '13 at 13:50
  • Still thank you for the answer, I have guessed about named function by myself, still, operator would be more straight-forward. I wish reinterpret_cast just .. well, interpreted the memory block without any questions what so ever. – Amomum May 21 '13 at 13:58
  • 1
    @Amomum: No; `operator Type()` is public, and `Type` can be used as an array index. – Mike Seymour May 21 '13 at 13:58
  • @Amomum: That is what `reinterpret_cast` does; but you'd need to cast to a reference (`reinterpret_cast`) in order to reinterpret the memory, and you'll get undefined behaviour since the types don't match. – Mike Seymour May 21 '13 at 14:00
  • Cast a reference?! o_O That's the first time I hear that. Thanks for the previous comment, but not using type conversion at all doesn't work in Keil (oddly enough) - it tries to use template operator and fails. – Amomum May 21 '13 at 14:09