определение типа C++ перечисление другого класса?

Я нашел решение для использования spring-cloud-zookeeper без Spring Boot, основываясь на представленной здесь идее https://wenku.baidu.com/view/493cf9eba300a6c30d229f49.html

Его следует легко обновить в соответствии с вашими потребностями и использовать сервер Spring Cloud Config (необходимо обновить класс CloudEnvironement, чтобы загрузить файл с сервера вместо Zookeeper)

Сначала создайте класс CloudEnvironement, который будет создайте PropertySource (например, из Zookeeper):

CloudEnvironement.java

  public class CloudEnvironment extends StandardServletEnvironment { 

  @Override 
  protected void customizePropertySources(MutablePropertySources propertySources) { 
    super.customizePropertySources(propertySources); 
    try { 
      propertySources.addLast(initConfigServicePropertySourceLocator(this)); 
    } 
    catch (Exception ex) { 
      logger.warn("failed to initialize cloud config environment", ex); 
    } 
  } 

  private PropertySource initConfigServicePropertySourceLocator(Environment environment) { 
    ZookeeperConfigProperties configProp = new ZookeeperConfigProperties(); 
    ZookeeperProperties props = new ZookeeperProperties(); 
    props.setConnectString("myzookeeper:2181"); 
    CuratorFramework fwk = curatorFramework(exponentialBackoffRetry(props), props); 
    ZookeeperPropertySourceLocator propertySourceLocator = new ZookeeperPropertySourceLocator(fwk, configProp); 
    PropertySource source= propertySourceLocator.locate(environment); 
    return source ; 
  } 

  private CuratorFramework curatorFramework(RetryPolicy retryPolicy, ZookeeperProperties properties) { 
    CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder(); 
    builder.connectString(properties.getConnectString()); 
    CuratorFramework curator = builder.retryPolicy(retryPolicy).build(); 
    curator.start(); 
    try { 
      curator.blockUntilConnected(properties.getBlockUntilConnectedWait(), properties.getBlockUntilConnectedUnit()); 
    } 
    catch (InterruptedException e) { 
      throw new RuntimeException(e); 
    } 
    return curator; 
  } 

  private RetryPolicy exponentialBackoffRetry(ZookeeperProperties properties) { 
    return new ExponentialBackoffRetry(properties.getBaseSleepTimeMs(), 
        properties.getMaxRetries(), 
        properties.getMaxSleepMs()); 
  } 

}

Затем создайте собственный класс XmlWebApplicationContext: он позволит загружать PropertySource из Zookeeper, когда запустите ваше веб-приложение и замените магию начальной загрузки Spring Boot:

MyConfigurableWebApplicationContext.java

public class MyConfigurableWebApplicationContext extends XmlWebApplicationContext { 

  @Override 
  protected ConfigurableEnvironment createEnvironment() { 
    return new CloudEnvironment(); 
  } 
}

Последняя, ​​в вашем файле web.xml добавьте следующий контекстный параметр для использования вашего класса MyConfigurableWebApplicationContext и начальной загрузки вашего CloudEnvironement.

           
      contextClass 
      com.kiabi.config.MyConfigurableWebApplicationContext 
     

Если вы используете стандартный конфигуратор файлов свойств, он все равно должен быть загружен, чтобы вы могли иметь свойства как в локальном файле, так и в Zookeeper.

Чтобы все это работало, вам нужно иметь в своем classpath файлы spring-cloud-starter-zookeeper-config и curator-framework jar с их зависимостью. Если вы используете maven, вы можете добавить следующее в pom.xml


        
            
                org.springframework.cloud
                spring-cloud-zookeeper-dependencies
                1.1.1.RELEASE
                pom
                import
            
        
    

    
        
            org.springframework.cloud
            spring-cloud-starter-zookeeper-config
        
        
            org.apache.curator
            curator-framework
        
    

12
задан rlbond 23 May 2009 в 18:10
поделиться

4 ответа

Я считаю, что A должно быть пространством имен, а не структурой.

3
ответ дан 2 December 2019 в 23:51
поделиться

Помещение перечислений в глобальную область видимости слишком открыто, размещение их в классе может привести к нежелательной зависимости. Для того, чтобы перечисление не было тесно связано с классом, я использую следующее:

#define CLEANENUMS_BEGIN(name) namespace name { typedef enum {
#define CLEANENUMS_END(name) } internal_ ## name ## _e;} typedef name::internal_ ## name ## _e name ## _e;

Затем вы можете использовать в глобальной области:

CLEANENUMS_BEGIN(myEnum)
    horizontal,
    vertical,
CLEANENUMS_END(myEnum)

Это более или менее имитирует способ C # обработки области действия перечислений. Препроцессор выдаст следующий код:

namespace myEnum
{
    enum internal_myEnum_e
    {
        horizontal,
        vertical,
    }
}
typedef internal_myEnum_e myEnum_e;

Затем на данное перечисление будет ссылаться как

myEnum_e val = myEnum::horizontal;

. Надеюсь, есть лучший способ сделать это, но пока это единственное решение, которое я нашел.

2
ответ дан 2 December 2019 в 23:51
поделиться

Why do you even have the test method in struct B? I don't think it makes any sense.

By defining struct A and defining an enum inside it, you are more or less saying that "here's an enum in scope of struct A" and this is the same as saying "if you want to use this enum, you have to refer to the struct A".

Putting the enum inside a namespace will not solve your problem. Because you will have the same scope problem (C4482)

I think you are making things too complicated. What do you think of this?

struct A
{
    enum A_enum
    {
        E0,
        E1,
        E2
    };

    static bool test(A_enum val)
    {
        return (val == E1);
    }
};


int main()
{
    assert(A::test(A::E1));
    return 0;
}

Note that A::test() is static. It should be because you aren't operating on the struct state. And since it's static, you dont need an instance of A to call the method.

-2
ответ дан 2 December 2019 в 23:51
поделиться

I've had the same issue in the past, and this is how I've fixed it. I wanted to be able to switch the implementation of a library at compile time. Одна из библиотек использовала такой код:

namespace Lib1 
{
  enum LibEnum { One, Two, Three };
  [...]
  void someFunc(LibEnum val);
}

В моем коде я хотел скрыть реализацию библиотеки от взаимодействия с пользователем (поэтому пользователь моего кода никогда не должен видеть, какую библиотеку я использую внутри):

Решение 1:

namespace MyCode 
{
  // Example to avoid copying a function from Lib1 here
  typedef Lib1::someFunc aFunctionImUsing;

  // This doesn't work
  // typedef LibEnum MyEnum; 
  // As such code doesn't compile:
  // aFunctionImUsing(One); // Error unknown identifier One
  // But this did:
  struct Type
  {
     enum MyType { One = Lib1::One, Two = Lib1::Two, Three = Lib1::Three };
  }
  static inline Lib1::LibEnum as(Type::MyType t) { return (Lib1::LibEnum)t; }

  // Now code like this compiles:
  aFunctionImUsing(as(Type::One));
  // This one doesn't:
  // aFunctionImUsing(Type::One); // Can't convert from Type::MyType to Lib1::LibEnum

  [...]
}

Решение 2:

namespace MyCode 
{
  struct Type
  {
     enum MyType { One = Lib1::One, Two = Lib1::Two, Three = Lib1::Three };
  }

  // If you don't care about polluting your namespace with numerous wrapper 
  // you can write this instead of typedef someFunc:
  static inline void myFunc(Type::MyType t) { return Lib1::someFunc((Lib1::LibEnum)t); }

  // This one does:
  myFunc(Type::One); 
  [...]
}

Это 2 проблемы с фрагментом кода выше. Первая проблема заключается в том, что вы должны скопировать и вставить перечисление в свое пространство имен (но с простым регулярным выражением в поиске и замене все готово). Вторая проблема заключается в том, что ваш пользователь должен будет использовать метод «as», что означает, что это непросто, или вам придется обернуть метод / функцию, используя второе решение.

В любом случае, поскольку невозможно ввести enum в пространстве имен, это лучшее решение, которое вы можете сделать. Обратите внимание, что ваш пользователь кода даже не знает, что вы используете библиотеку Lib1 в примере кода.

0
ответ дан 2 December 2019 в 23:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: