Обязательная инициализация массива
От: SaZ  
Дата: 05.03.13 15:03
Оценка:
Доброго времени суток,

Существует 2 enum-а: UserRole (гость, оператор, админ) и Storage (хранилище1, хранилище2...)
Первый enum вряд ли будет расширяться, второй будет расширяться по мере добавления новых модулей в проект.

Нужно написать функцию, которая в зависимости от роли пользователя и типа хранилища вернёт true или false. Т.е. своего рода "таблица истинности":
bool isAccessEnabled( UserRole role, Storate storage )
{
  switch ( storage )
  {
  case st1:
    switch ( role )
    {
    case guest:
      return false; // Значения, определяемые логикой работы приложения
    case moderator:
      return true;
    case admin:
      return true;
    }
    break;

  case s22:
    switch ( role )
    {
    case guest:
      return true; // Значения, определяемые логикой работы приложения
    case moderator:
      return true;
    case admin:
      return true;
    }
    break;
  // ...
  }
  // ...
}


Вопрос: каким образом лучше решать такие задачи?

Можно, конечно, явно "хардкодить" всю логику, выкидывать ненужные case-ы (например, if ( role == admin ) return true, можно объявить bool массив.
Но в идеале хотелось бы решения, которое бы в compile time выдавало ошибку, если какие-то состояния явно не определены.
c++ templates array initialization
Re: Обязательная инициализация массива
От: SaZ  
Дата: 05.03.13 15:12
Оценка:
Пока на ум приходит только делать через шаблоны и частичную специализацию. Хочется только покрасивее это оформить.
Re: Обязательная инициализация массива
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 05.03.13 15:16
Оценка: :)
Здравствуйте, SaZ, Вы писали:

SaZ>Доброго времени суток,


SaZ>Существует 2 enum-а: UserRole (гость, оператор, админ) и Storage (хранилище1, хранилище2...)

SaZ>Первый enum вряд ли будет расширяться, второй будет расширяться по мере добавления новых модулей в проект.
Твою дивизию... Неужели туту можно заиспользовать шаблон Visitor?!
Sic luceat lux!
Re: Обязательная инициализация массива
От: Vzhyk  
Дата: 05.03.13 15:40
Оценка: +1
On 05.03.2013 18:03, SaZ wrote:

> Можно, конечно, явно "хардкодить" всю логику, выкидывать ненужные case-ы

> (например, if ( role == admin ) return true, можно объявить bool массив.
Ну можно табличку 2х3, но понятно нынче тру-програмеры простыми путями
не ходят.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Обязательная инициализация массива
От: SaZ  
Дата: 05.03.13 15:48
Оценка:
Здравствуйте, Vzhyk, Вы писали:

V>On 05.03.2013 18:03, SaZ wrote:


>> Можно, конечно, явно "хардкодить" всю логику, выкидывать ненужные case-ы

>> (например, if ( role == admin ) return true, можно объявить bool массив.
V>Ну можно табличку 2х3, но понятно нынче тру-програмеры простыми путями
V>не ходят.

Под bool массивом я и понимал табличку 2 на 3: bool result[2][3] = { 0/*...*/ };
Хочется чего-то более наглядного. Я понимаю, что задача выглядит примитивной, но надо же когда-то учиться
Re[3]: Обязательная инициализация массива
От: Vzhyk  
Дата: 05.03.13 15:57
Оценка: +3
On 05.03.2013 18:48, SaZ wrote:

> Под bool массивом я и понимал табличку 2 на 3: bool result[2][3] = {

> 0/*...*/ };
> Хочется чего-то более наглядного. Я понимаю, что задача выглядит
> примитивной, но надо же когда-то учиться
Куда уж нагляднее?
Или у тебя задача писать код долго и сложно и большим количеством
строчек, чтобы после тебя никто не догадался что же он делает?
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Обязательная инициализация массива
От: SaZ  
Дата: 05.03.13 16:39
Оценка:
Здравствуйте, Vzhyk, Вы писали:

V>Или у тебя задача писать код долго и сложно и большим количеством

V>строчек, чтобы после тебя никто не догадался что же он делает?

Да скорее хотелось поизвращаться с шаблонами (так уж сложилось, что я с ними практически не работал, за исключением использования готовых классов qt, буста и стл).
Как-то так
#define DECLARE_MODULE_PERMISSION( role, module, result )   \
    template <>                                             \
    struct IsModuleAvailable< role, module >                \
    {                                                       \
        inline operator bool() const                        \
        {                                                   \
            return result;                                  \
        }                                                   \
    }


    template < UserRole role, Module module >
    struct IsModuleAvailable;

    DECLARE_MODULE_PERMISSION( Employee , QueueMonitor   , false );
    DECLARE_MODULE_PERMISSION( Employee , CallHistory    , true  );

    bool result = IsModuleAvailable< Employee, CallHistory >();


Поигрался, получилось, успокоился.
Re[5]: Обязательная инициализация массива
От: Evgeny.Panasyuk Россия  
Дата: 05.03.13 16:49
Оценка:
Здравствуйте, SaZ, Вы писали:

SaZ>Да скорее хотелось поизвращаться с шаблонами (так уж сложилось, что я с ними практически не работал, за исключением использования готовых классов qt, буста и стл).

SaZ> bool result = IsModuleAvailable< Employee, CallHistory >();
SaZ>Поигрался, получилось, успокоился.

Если нужно тестировать только compile-time значения (а не runtime, как в исходном сообщении), то посмотри на boost::mpl::map:

typedef map<
      pair<int,unsigned>
    , pair<char,unsigned char>
    , pair<long_<5>,char[17]>
    , pair<int[42],bool>
    > m;

BOOST_MPL_ASSERT_RELATION( size<m>::value, ==, 4 );
BOOST_MPL_ASSERT_NOT(( empty<m> ));

BOOST_MPL_ASSERT(( is_same< at<m,int>::type, unsigned > ));
BOOST_MPL_ASSERT(( is_same< at<m,long_<5> >::type, char[17] > ));
BOOST_MPL_ASSERT(( is_same< at<m,int[42]>::type, bool > ));
BOOST_MPL_ASSERT(( is_same< at<m,long>::type, void_ > ));
Re: Обязательная инициализация массива
От: LaptevVV Россия  
Дата: 05.03.13 17:02
Оценка: 1 (1)
Здравствуйте, SaZ, Вы писали:

SaZ>Нужно написать функцию, которая в зависимости от роли пользователя и типа хранилища вернёт true или false. Т.е. своего рода "таблица истинности":

SaZ>Вопрос: каким образом лучше решать такие задачи?

SaZ>Можно, конечно, явно "хардкодить" всю логику, выкидывать ненужные case-ы (например, if ( role == admin ) return true, можно объявить bool массив.

SaZ>Но в идеале хотелось бы решения, которое бы в compile time выдавало ошибку, если какие-то состояния явно не определены.
Мультиметоды спасут отца русской демократии?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Обязательная инициализация массива
От: LaptevVV Россия  
Дата: 05.03.13 17:02
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, SaZ, Вы писали:


SaZ>>Доброго времени суток,


SaZ>>Существует 2 enum-а: UserRole (гость, оператор, админ) и Storage (хранилище1, хранилище2...)

SaZ>>Первый enum вряд ли будет расширяться, второй будет расширяться по мере добавления новых модулей в проект.
K>Твою дивизию... Неужели туту можно заиспользовать шаблон Visitor?!
ИМХО попроще — мультиметоды...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[5]: Обязательная инициализация массива
От: rg45 СССР  
Дата: 05.03.13 21:08
Оценка: 14 (2)
Здравствуйте, SaZ, Вы писали:

SaZ>Здравствуйте, Vzhyk, Вы писали:


V>>Или у тебя задача писать код долго и сложно и большим количеством

V>>строчек, чтобы после тебя никто не догадался что же он делает?

SaZ>Да скорее хотелось поизвращаться с шаблонами (так уж сложилось, что я с ними практически не работал, за исключением использования готовых классов qt, буста и стл).

SaZ>Как-то так
SaZ> . . .

SaZ>Поигрался, получилось, успокоился.



Когда результат зависит только от двух констант компиляции, было бы логично получать его также на этапе компиляции, это ведь не влечет ни дополнительных расходов ни ограничений, а полезным оказаться может:
#define DECLARE_MODULE_PERMISSION( role, module, result )   \
    template <>                                             \
    struct IsModuleAvailable<role, module>                  \
    {                                                       \
      static const bool value = result;                     \
    }


    template < UserRole role, Module module >
    struct IsModuleAvailable;

    DECLARE_MODULE_PERMISSION( Employee , QueueMonitor   , false );
    DECLARE_MODULE_PERMISSION( Employee , CallHistory    , true  );

    enum Foo
    { 
      bar = IsModuleAvailable<Employee, CallHistory>::value;
    };
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Обязательная инициализация массива
От: SaZ  
Дата: 06.03.13 07:59
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Мультиметоды спасут отца русской демократии?

Спасибо, обязательно почитаю
Автор(ы): Клюев Александр
Дата: 19.07.2003
Мультиметоды — виртуальные функции, принадлежащие сразу нескольким классам. В статье разбирается суть мультиметодов, их особенности, а также возможная реализация мультиметодов на C++.
.
Re[6]: Обязательная инициализация массива
От: SaZ  
Дата: 06.03.13 08:02
Оценка:
Здравствуйте, rg45, Вы писали:

R>Когда результат зависит только от двух констант компиляции, было бы логично получать его также на этапе компиляции, это ведь не влечет ни дополнительных расходов ни ограничений, а полезным оказаться может:

R>...

Благодарю. Я думал, что с включенной оптимизацией inline + const будет достаточно для такого поведения.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.