Членове на C++ const израз за превключване на регистъра

Бих искал някакъв начин да оценя израз на клас за превключване, използвайки членове на класа, които не са цели числа или eum.

Истинският въпрос е как да направим тези членове на класа const-expression, т.е. тези членове трябва да бъдат известни като постоянни по време на компилиране.

Опитах кода по-долу с static const, но работи само когато в операторите case има цели числа.

Гледах нов C++11 constexpr, който щеше да свърши работа.

Какво ще стане, ако нямам налична тази ключова дума? Има ли все пак или трик или нещо, което да позволи на членовете на моя клас (не цяло число или enum) да бъдат константни изрази?

Използвам Linux и g++. Също така всяка специфична ключова дума за g++ ще бъде оценена.

  class MyEnum
  {
  public:
    int val_;
    MyEnum(){}
    MyEnum(int v): val_(v){}
    operator int(){return val_;}
    static const MyEnum ALFA;
    static const MyEnum BETA;
    void foo() {
       // do something.
    }
  };

  const MyEnum MyEnum::ALFA(1);
  const MyEnum MyEnum::BETA(2);

  void testEnum()
  {
    MyEnum val = MyEnum::ALFA;

    switch(val)
    {
      case 0: //works
      //case MyEnum::ALFA:// doesn't work
      cout << "ciao" << endl;
      break;
      case 1: //works
      //case MyEnum::BETA: // doesn't work
      cout << "bello" << endl;
      break;
      default:
      break;
    } 
  }

person Abruzzo Forte e Gentile    schedule 10.04.2014    source източник
comment
Какво ще кажете за typecast вашето const MyEnum към int? :)   -  person Orelsanpls    schedule 10.04.2014
comment
това, което наистина искате, е да сравните стойността на MyEnum. защо не if( val == MyEnum::ALFA) //...   -  person 4pie0    schedule 10.04.2014
comment
Знаете ли, че MyEnum::ALFA == MyEnum::BETA (и че инициализирате и двете до нула?)   -  person Massa    schedule 10.04.2014
comment
здрасти Съжалявам, че редактирах кода. Класът също трябва да направи нещо, така че трябва да има и методи.   -  person Abruzzo Forte e Gentile    schedule 10.04.2014
comment
@RaNdoM_PoWneD: Опитах case static_cast‹int›(MyEnum::ALFA) и не работи.   -  person Abruzzo Forte e Gentile    schedule 10.04.2014
comment
@Massa: Редактирах, за да върна различна стойност. Имам нужда от начин да оценя MyEnum::ALFA като const-израз.   -  person Abruzzo Forte e Gentile    schedule 10.04.2014


Отговори (2)


Това изглежда прави това, което искате:

#include <iostream>

enum class MyEnum { ALFA, BETA };

int main() {
    MyEnum a = MyEnum::BETA;

    switch( a ) {
        case MyEnum::ALFA:
            std::cout << "ALFA\n";
            break;
        case MyEnum::BETA:
            std::cout << "BETA\n";
            break;
    }
}

РЕДАКТИРАНЕ:

Според коментара на Едуард по-долу, ето пример за това как можете да имате това без enum (в моя случай enum class -- което създава нов тип) или int:

#include <iostream>

class MyEnum {
    struct Alfa { constexpr operator int() const { return 0; } };
    struct Beta { constexpr operator int() const { return 1; } };
    int v;
public:
    constexpr static Alfa ALFA {};
    constexpr static Beta BETA {};
    MyEnum(const MyEnum&) = default;
    constexpr MyEnum(Alfa vv): v(vv) {}
    constexpr MyEnum(Beta vv): v(vv) {}
    constexpr MyEnum() : MyEnum(ALFA) {}
    operator int () const { return v; }
};

int main() {
    MyEnum a = MyEnum::BETA;
    a = MyEnum::ALFA;

    switch( a ) {
        case MyEnum::ALFA:
            std::cout << "ALFA\n";
            break;
        case MyEnum::BETA:
            std::cout << "BETA\n";
            break;
    }
}

Това е много по-сложно (на живо тук) :D

person Massa    schedule 10.04.2014
comment
Това е разумен код, но изглежда, че въпросът изисква нещо малко по-различно. По-конкретно първият ред поиска превключване, използвайки членове на класа, които не са цяло число или enum. - person Edward; 10.04.2014
comment
@Massa: вашето решение ме интересува, но за съжаление не се вгражда в g++. Забелязах, че е кодиран с clang, който не мога да използвам за моите цели. - person Abruzzo Forte e Gentile; 11.04.2014
comment
@AbruzzoForteeGentile работи за мен и на g++ (вижте тук); какъв е проблема, който имаш? - person Massa; 11.04.2014
comment
@Massa забрави за коментара ми. Току-що разбрах, че имам g++ 4.4 ..твърде стар за constexpr - person Abruzzo Forte e Gentile; 11.04.2014
comment
@Massa: Страхотни неща! В крайна сметка изпробвах второто ви решение и то работи добре дори при използване на член на клас, който също търсех. Използването на constexpr във втория пример е страхотно. - person Abruzzo Forte e Gentile; 11.04.2014

Ето начин да направите нещо като това, което мисля, че питате. Промених вашия MyEnum клас, така че да е `constexpr, а променливата val, така че да е int. ALFA и BETA са екземпляри на MyEnum, а не едновременно екземпляри и членове, както във вашия оригинален код. Само за да направи нещата интересни, операторът за предаване прави повече от просто връщане на вътрешния data.

#include <iostream>
using namespace std;

class MyEnum
{
public:
    constexpr MyEnum(int n) : data(n) {}
    constexpr operator int(){return data+5;}
private:
    int data;
};

static constexpr MyEnum ALFA{0};
static constexpr MyEnum BETA{1};

void testEnum()
{
    int val = 5;

    switch(val)
    {
    case int(ALFA):
        cout << "ciao" << endl;
        break;
    case int(BETA):
        cout << "bello" << endl;
        break;
    default:
        break;
    } 
}

int main()
{
    testEnum();
}

Това отпечатва ciao както се очаква.

person Edward    schedule 10.04.2014