"Enum Class" Emulation or Solid Alternative for Msvc 10.0

enum class emulation or solid alternative for MSVC 10.0

I just discovered a problem with James' good hack (which I have heretofore been using), and a fix to the problem. I discovered the problem when I tried to define a stream operator for my_enum.

#include <iostream>

struct my_enum {
enum type {
value1,
value2
};

my_enum(type v) : value_(v) { }

operator type() const { return value_; }

private:

type value_;
};

std::ostream&
operator<<(std::ostream& os, my_enum v)
{
return os << "streaming my_enum";
}

int main()
{
std::cout << my_enum::value1 << '\n';
}

The output is:

0

The problem is my_enum::value1 has different type than my_enum. Here's a hack to James' hack that I came up with.

struct my_enum
{
static const my_enum value1;
static const my_enum value2;

explicit my_enum(int v) : value_(v) { }

// explicit // if you have it!
operator int() const { return value_; }

private:

int value_;
};

my_enum const my_enum::value1(0);
my_enum const my_enum::value2(1);

Notes:

  1. Unless otherwise specified by an enum-base, the underlying type of a scoped enumeration is int.
  2. Explicit conversions to and from the underlying integral type are allowed. But implicit conversions are not. Do your best.
  3. This hack is more of a pita than James' because of the need to enumerate the values twice. I'm hoping compilers without scoped enum support rapidly become extinct!

Do we really need enum class in C++11?

Besides what was already mentioned, an advantage of enum class is better type safety - the enum class enumerators don't convert implicitly to integers.

C++ enum equivalent - convert to constant expression

There is no function-call operator declared here.

operator int const() const { return myVal; }

Is a user-defined conversion which converts an object of type DeletionMode_E to a constant integer. To invoke it, you have to perform a cast (this is done implicitly in your switch-statement).

Inline namespace emulation for MSVC (10.0/11.0)

I'm afraid there is no possibility of such emulation. Microsoft seems to be very uninterested in symbol versioning, even though they break ABI on their standard library on every single new revision of their compiler. The GCC emulation works because strong using was the basis for the inline namespace feature. Microsoft never had a similar thing, so you can't emulate inline namespaces. I'm afraid you're stuck with not versioning libc++ for now.

There is one feature in Microsoft's compiler that may help. This is #pragma detect_mismatch:
http://msdn.microsoft.com/en-us/library/ee956429.aspx

Basically, you put

#pragma detect_mismatch("libcxx_version", "1.0")

into a central libc++ header file, and every module that includes that file will have a record placed in it that contains the key and value. The Microsoft linker checks, when linking modules, that all such records have the same value for any given name, and complains if there is a mismatch.

The end result is that you can't have multiple parallel versions of libc++ in a single program, but at least you won't get silent corruption from linking incompatible object files that cause nasty crashes at runtime.

Edit: forgot to mention: this feature is new in VS2010, but porting libc++ to a compiler without rvalue refs is probably rather hopeless anyway.

MSVC 10.0 c vs c++ differences

The problem might be the place where variable declarations are going. Place them at the beginning of the function with the other variables.

See the last example from MSDN that can cause this error code.

Replacing enum with class with int identifiers - doesn't compile

the latest C++ standard doesn't regard an enum to be equivalent to an int

The specification of enum has not changed: an enumerator is still implicitly convertible to its underlying integral type.

C++11 adds a new concept, enum class, which is a "strongly typed and scoped enum." This new kind of enumeration does not allow its enumerators to be implicitly converted to the underlying integral type (though, you can explicitly coerce the conversion using static_cast).

If you want to write your own scoped enumeration that provides semantics and behavior similar to enum class but is usable on compilers that do not support enum class, you should read Howard Hinnant's answer to this other question, wherein he provides a working example.

Correct way to use enums with pass-by-value and return in functions?

Personally I use a very simple trick:

struct EnumName
{
enum type {
MemberOne,
MemberTwo,
...
};
};

typedef EnumName::type EnumName_t;

// Usage
EnumName_t foo = EnumName::MemberOne;

In C++0x, you can have scoped enumerators directly:

enum struct EnunName // note: struct and class equivalent here
{
MemberOne,
MemberTwo,
...
};

// Usage
EnumName foo = EnumName::MemberOne;

Which will be really great :)

Note: scoped enum are also not subject to integral promotion, which is really great

C++11 Polyfills

This is what you'll need to do (I made other trivial fixes about pointers and non-pointer access).
Bsically, it's what @demi said. I had to make a dummy enum name. This works in g++-4.7.

class MyClass {
public:
#if __cplusplus > 201000
enum class MyEnumerator : unsigned int {
EnumValue = 0
};
void method(MyEnumerator e) {}
#else
class MyEnumerator {
public:
enum Dummy {
EnumValue = 0
};
};
void method(MyEnumerator::Dummy e) {}
#endif
};

int main() {
MyClass mc;
mc.method(MyClass::MyEnumerator::EnumValue); // C++11 or C++03
}

Enum inside enum on C++

Ok, making some proofs I have finally solved it using overload. I've removed the ObjectTypes by overloading the method and creating three different structs:

struct KeyboardTypes {
enum types{
DEFAULT
};
};
struct MouseTypes {
enum types{
DEFAULT,
INVERSE
};
};
struct HapticTypes {
enum types{
DEFAULT
};
};

And the overloaded member function:

void changeInputSystem(SimulatorConstants::MouseTypes::types type);
void changeInputSystem(SimulatorConstants::KeyboardTypes::types type);
void changeInputSystem(SimulatorConstants::HapticTypes::types type);

Thanks to everyone who has helped.

How to enable external request in IIS Express?

There's a blog post up on the IIS team site now explaining how to enable remote connections on IIS Express. Here is the pertinent part of that post summarized:

On Vista and Win7, run the following command from an administrative prompt:

netsh http add urlacl url=http://vaidesg:8080/ user=everyone

For XP, first install Windows XP Service Pack 2 Support Tools. Then run the following command from an administrative prompt:

httpcfg set urlacl /u http://vaidesg1:8080/ /a D:(A;;GX;;;WD)



Related Topics



Leave a reply



Submit