>source

C++11로 메타프로그래밍을 하고 있습니다.

스위치 문과 지도의 키워드로 사용할 수 있지만 Java 열거형과 같은 객체와 유사한 속성을 갖고 있는 EnumWrapper를 만들고 싶습니다.

수업:

#include <string>#include <vector>template<typename T, int len>class Enum
{
  private:
    typename T::Value value; //invalid use of incomplete Type Planet
  public:
    Enum()= delete;
    constexpr Enum( typename T::Value key ) : value( key ) //invalid use of incomplete Type Planet
    {
    }
    //Allow switch and comparisons.
    operator typename T::Value() const //invalid use of incomplete Type Planet
    {
        return value;
    }
    T&amp;
 operator=( const T&amp;
 other )
    {
        this->value= other.value;
        return *this;
    }
    inline typename T::Value getValue() //invalid use of incomplete Type Planet
    {
        return value;
    }
    explicit operator bool()= delete;
    Enum&amp;
 operator=( const Enum&amp;
 p )
    {
        this->value= p.value;
        return *this;
    }
    static inline int length()
    {
        return len;
    }
    static std::vector<T> values()
    {
        std::vector<T> values;
        values.reserve( length() );
        for ( int i= 0; i < length(); i++ )
        {
            values.push_back( (typename T::Value)i ); //This is fine for some reason
        }
        return values;
    }
    static T getMember( std::string name )
    {
        for ( T p : values() )
        {
            if ( p.name()== name )
            {
                return p;
            }
        }
    }
};
class Planet : Enum<Planet, 3>{
  public:
    enum Value
    {
        MERCURY,
        VENUS,
        EARTH
    }
    std::string name()
    {
         switch(this->getValue())
         {
             case MERCURY:
                 return "Mercury";
             case EARTH:
                 return "Mercury";
             case VENUS:
                 return "Mercury";
         }
    }
};

컴파일러는 "불완전한 유형 행성의 잘못된 사용" 메시지를 여러 개 제공합니다.

클래스를 하나의 단일 클래스로 병합할 때 code는 의도적으로 컴파일되고 작동합니다. 그러나 재사용 가능성과 유지 관리 가능성은 병합된 접근 방식으로 제공되지 않습니다.

누군가 이 오류 메시지를 도와줄 수 있습니까?

추가 정보가 필요하거나 원하는 경우 알려주십시오.

수정: 내 의도 된 사용은 다음과 같습니다.

int main()
{
    Planet planet    = Planet::EARTH;
    Planet invalidPlanet= Planet( (Planet::Value)5 );
    //Naming funktioniert...
    std::cout << "My Planet is named " << planet.name() << std::endl;
    //... und beliebig  erweiterbar (denkbar wären auch Lambdas!)
    Planet venus= Planet::VENUS;
    std::cout << "Gravity of Venus is " << venus.gravitation() << std::endl;
    //Switch funktioniert
    switch ( planet )
    {
    case Planet::VENUS:
        std::cout << "Venus found." << std::endl;
        break;
    case Planet::EARTH:
        std::cout << "Earth found." << std::endl;
        break;
    default:
        std::cout << "Nothing found." << std::endl;
        break;
    }
    //simple comparison
    bool isEarth= planet== Planet::EARTH; //true
    bool isVenus= planet== Planet::VENUS; //false
    std::cout << "Planet is earth: " << ( isEarth ? "true" : "false" ) << std::endl;
    std::cout << "Planet is venus: " << ( isVenus ? "true" : "false" ) << std::endl;
    //works in Map
    std::map<Planet, std::string> myMap;
    myMap[ planet ]= "MyEarth";
    std::cout << "chosen planet: " << myMap[ Planet::MERCURY ] << std::endl;
    std::cout << "chosen planet: " << myMap[ Planet::EARTH ] << std::endl;
    //Map is not bound to object but bound to enum integer
    Planet fakeEarth= Planet::EARTH;
    std::cout << "chosen planet: " << myMap[ fakeEarth ] << std::endl;
    return 1;
}

이렇게 생각하십시오. 클래스 Planet에 대한 정의는 Value를 얻기 위해 자신의 정의에 효과적으로 의존합니다.

AndyG2021-09-24 01:36:12

흥미로운 문제. 가장 먼저 떠오르는 해결책은 Value의 정의를 Planet에서 분리하여 Enum에 별도로 전달하는 것입니다. 어떻게 결합할 수 있는지 모르겠습니다. 반환 직후 중단은 중복됩니다.

François Andrieux2021-09-24 01:36:12

@AndyG 이 "정의 순서" 문제를 이해합니다. 하지만 해결할 수 있는 방법이 있습니까? 내가 시도한 또 다른 시도는 Value를 템플릿 인수로 전달하는 것이었습니다. 그러나 이것은 같은 이유로 작동하지 않습니다.

A1192021-09-24 01:36:12

참고: 이름과 일치하지 않는 경우 Enum::getMember는 무엇을 반환합니까? 지금은 그냥 돌아오지 않고 끝난다. 아마도 던질까요?

AndyG2021-09-24 01:36:12

@FrançoisAndrieux 물론이죠! 더 이상의 혼란을 피하기 위해 편집했습니다. 또한 내 문제에 대한 더 나은 느낌을 주기 위해 사용 사례를 추가했으며 열거형을 중첩하려는 이유(단단한 구문)

A1192021-09-24 01:36:12
  • 이전 javascript : Twitter처럼 클릭할 때마다 좋아요 아이콘의 색상을 변경하고 싶습니다.
  • 다음 c# : 레이블에 지수를 표시하는 방법은 무엇입니까?