C ++ 11 to convert enums?

I have an enumeration like:

enum E
{
    TYPE_FLOAT,
    TYPE_CHAR,
    TYPE_INT
}

And I want to create a compile-time mapping to get the corresponding E for a type of type:

GetE<float> // returns TYPE_FLOAT
GetE<char> // returns TYPE_CHAR
GetE<int> // returns TYPE_INT

I thought:

template<class T> struct GetE;

template<> struct GetE<float> { static constexpr E type = TYPE_FLOAT; };
template<> struct GetE<char> { static constexpr E type = TYPE_CHAR; };
template<> struct GetE<int> { static constexpr E type = TYPE_INT; };

But I get errors like:

undefined reference to `GetE<int>::type'

What is the best way to do this? And why a mistake?

+5
source share
3 answers

It depends on how you use these constant expressions.

The ODR (one-definition rule) states that

(§3.2 / 2) [...] A variable whose name is displayed as a potentially evaluable expression is used by odr if it is not an object that satisfies the requirements for displaying in the constant expression (5.19) and lvalue to-rvalue (4.1) is immediately applied . [...]

( , .)

, odr, . , , , .

, :

int main() {
  E e = GetE<float>::type;
  return 0;
}

:

void f(const E &)
{ }

int main() {
  f(GetE<float>::type);
  return 0;
}

f (const), lvalue-to-rvalue , odr. , .

(. (. ), , , . , -O0 ( , ).)

, , struct-definition:

constexpr E GetE<float>::type;
constexpr E GetE<char>::type;
constexpr E GetE<int>::type;

.cpp( ), , .

, , .. constexpr ( ), :

template <class T> constexpr E GetE();

template <> constexpr E GetE<float>()
{ return TYPE_FLOAT; }

template <> constexpr E GetE<char>()
{ return TYPE_CHAR; }

template <> constexpr E GetE<int>()
{ return TYPE_INT; }

void f(const E &)
{ }

int main() {
  E e = GetE<float>();

  f(GetE<float>());

  return 0;
}
+6

- :

class C {
    const static int x = 5;
};

decltype(C::x) C::x;
+1

, , , LiveWorkSpace:

#include <iostream>

enum E
{
   TYPE_FLOAT,
   TYPE_CHAR,
   TYPE_INT
} ;

template<class T> struct GetE;

template<> struct GetE<float> { static constexpr E type = TYPE_FLOAT; };
template<> struct GetE<char> { static constexpr E type = TYPE_CHAR; };
template<> struct GetE<int> { static constexpr E type = TYPE_INT; };

int main()
{
    std::cout << GetE<int>::type << std::endl ;
}

http://liveworkspace.org/code/nHqUe $6

+1

All Articles