В C++, как я могу избежать #including заголовочный файл, когда я должен использовать перечисление?

Я понял это. CloudWatch Exporter позволяет передавать роль IAM arn через атрибут config role_arn. Если это значение установлено, то приложение использует STSAssumeRoleSessionCredentialsProvider для установки учетных данных. Это явно не поддерживается в Fargate (этот метод работает в контейнерах ECS на основе EC2). Если вы выключите role_arn, то приложение создаст нового клиента с настройками по умолчанию, который использует класс DefaultAWSCredentialsProviderChain, и это работает как чудо.

5
задан chrisp451 25 March 2009 в 11:50
поделиться

8 ответов

Вы не можете передать, объявляют перечислимые значения - и Ваше обходное решение является шагом вниз путь для завершения безумия.

Вы испытываете какое-либо основное замедление компиляции, вызванное #including заголовками? В противном случае просто #include их. Использование предописаний не является "лучшей практикой", это - взлом.

6
ответ дан 18 December 2019 в 05:50
поделиться

Это трудно сделать приятно. Возможно, перемещение enums к общему заголовочному файлу было бы разумное решение?

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

12
ответ дан 18 December 2019 в 05:50
поделиться

Перечисления 0x C++ со строгим контролем типов могут быть вперед объявлены. GCC 4.4.0 и CodeGear Разработчик C++ 2009 поддерживают перечисления со строгим контролем типов.

Существует несколько подобных перечислению классов, плавающих вокруг подобного (предложены, но никогда не завершены и приняты) Повышение. Перечисление доступное для скачивания от Хранилища Повышения в этой ссылке. Начиная с Повышения. Перечисления являются классами, они могут быть вперед объявлены.

Однако просто помещение перечислений в отдельном файле (как в этом ответе) кажется самым простым, лучшим решением (запрещающий C++ 0x поддержка).

4
ответ дан 18 December 2019 в 05:50
поделиться

Можно использовать предописания только, когда Вы объявляете указатель. Если Вы объявляете неуказательную переменную, необходимо будет включать соответствующий заголовочный файл.

Так как перечислимая переменная не является указателем, Вы не можете использовать предописания. И я не думаю, что существует альтернативное решение.

4
ответ дан 18 December 2019 в 05:50
поделиться

Можно использовать аргументы шаблона для программы против 'общих' перечислимых типов. Во многом как это:

// enum.h
struct MyClass1 { enum e { cE1, cE2, cELast }; };

// algo.h
// precondition: tEnum contains enumerate type e
template< typename tEnum > typename tEnum::e get_second() { 
    return static_cast<typename tEnum::e>(1); 
}

// myclass1.h

// myclass.h
template< typename tClass1 >
class MyClass2
{
    tClass1 * ptr;
    void func( tClass1::e e );
};
// main.cpp
#include "enum.h"
#include "algo.h"
int main(){ return get_second<Enum>(); }
2
ответ дан 18 December 2019 в 05:50
поделиться

Я не думаю (я могу быть доказан неправильным), что можно передать, объявляют внутренний тип, ни перечисление. Вам будет нужно определение класса включения для использования перечисления.

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

1
ответ дан 18 December 2019 в 05:50
поделиться

Предописание перечислений было на самом деле предложено комитетом по стандартам C++. Посмотрите эту бумагу (PDF). Это, конечно, была бы хорошая функция!

0
ответ дан 18 December 2019 в 05:50
поделиться

При реальном столкновении с замедлением компиляции из-за включения заголовка другая опция состоит в том, чтобы использовать int вместо enum. Это - довольно непопулярный подход, так как он ухудшает безопасность типов. Если бы Вы действительно проявляете этот подход, то я также рекомендовал бы добавить код, чтобы программно сделать проверку границ:

// in class1.h
class Class1 {
public:
    enum Blah {
       kFirstBlah, // this is always first
       eOne = kFirstBlah,
       ...
       kLastBlah // this is always last
    };
};

// in checks.h
#include <stdexcept>
namespace check {
template <typename T, typename U>
U bounds(U lower, T value, U upper) {
    U castValue = static_cast<U>(value);
    if (castValue < lower || castValue >= upper) {
        throw std::domain_error("check::bounds");
    }
    return castValue;
}
} // end check namespace

// in class2.h
class Class2 {
public:
    void func(int blah);
};

// in class2.cpp
#include "class2.h"
#include "class1.h"
#include "checks.h"

void Class2::func(int blah) {
    Class1::Blah blah_;
    blah_ = check::bounds(Class1::kFirstBlah, blah, Class1::kLastBlah);
}

Это не самое симпатичное решение, но это действительно решает проблему зависимости от заголовка путем перемещения части безопасности типов, которую статическая компиляция дает Вам в код во время выполнения. Я имею аналогичные подходы использования в прошлом и нашел это a check пространство имен, используемое таким образом, может сделать получающийся код почти столь же читаемым как enum основанный код с очень небольшим усилием.

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

0
ответ дан 18 December 2019 в 05:50
поделиться
Другие вопросы по тегам:

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