Перейти к содержанию
    

Как в C (C++) написать красиво проверку, что несколько переменных равны?

Мне? Мне надо красиво (т. е. просто) записать эту проверку. И пока что банальная проверка равенства всех констант с одной - лучшая. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А тот вариант, что я предложил выше? Вроде, вполне красиво:
 

static_assert(isEqual(a1, a2, a3), "vars are not equal!");

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Наверное, красиво. Но где бы почитать, чтобы понять, что там написано? :unknw: Про вариативные шаблоны. Куда ни загляну, ничего не понимаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно почитать здесь.

Из книжек - рекомендую "Галовиц Яцек - C++17 STL. Стандартная библиотека шаблонов". Найти можно, например, здесь.
Там достаточно неплохо  описаны нововведения  c++ 17.

Изменено пользователем AHTOXA

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кейл выдает ошибки.

error:  #3100: "auto" function requires a trailing return type

Первую убрал так:

template <typename T, typename... Types>
constexpr T firstArg(T arg, Types... )

Вторую не могу  Заменил на bool:

template <typename T, typename... Types>
constexpr auto isEqual(T arg, Types... args)

Дальше пошли ошибки:

error:  #125: expected a "("

      if constexpr (sizeof... (args) > 1)

Наверное, компилятор Кейла v5.06 этого (...) не умеет.  

 

Изменено пользователем ViKo

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, AHTOXA said:

Из книжек - рекомендую

А не порекомендуете в контексте ещё хорошие книги по "крутому использованию" Си++11, 14, 17. На всякий случай, мой компилятор IAR 8.32. Он точно умеет 14. Ага, сейчас посмотрел, 17 не поддерживает((( Заранее спасибо)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для меня лучшая книга 
Стивен Прата  Язык программирования  С++.  Лекции и упражнения 
6-е издание 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

23 минуты назад, AHTOXA сказал:

Но можно и без этого обойтись

В main.cpp такой static_assert проходит.

А когда пытаюсь использовать в шаблоне класса, выдается ошибка:

error:  #3673: function call must have a constant value in a constant expression
        static_assert(isEqual(g00, g01, g02, g03, g04, g05, g06, g07,

Хотя там же мой static_assert проходит.

    static_assert(  g00 == g01 && g00 == g02 && g00 == g03 && g00 == g04 &&
                    g00 == g05 && g00 == g06 && g00 == g07 && g00 == g08 &&
                    g00 == g09 && g00 == g10 && g00 == g11 && g00 == g12 &&
                    g00 == g13 && g00 == g14 && g00 == g15, "The Port isn't the same!");

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, haker_fox сказал:

А не порекомендуете в контексте ещё хорошие книги по "крутому использованию" Си++11, 14, 17.

Скотт Мейерс — Эффективный и современный С++. 42 рекомендации по использованию C++11 и C++14

Изменено пользователем Grizzly

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, ViKo сказал:

Наверное, компилятор Кейла v5.06 этого (...) не умеет.  

Он только C++11 поддерживает. Переходите с armcc на armclang, если ваш девайс не совсем древний (иначе не будет поддержки со стороны toolchain).

https://developer.arm.com/docs/100067/latest/Armclang-command-line-options/-std

Изменено пользователем Grizzly

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тоже однажды хотел сравнить результаты вычислений 32 выражений и выдать предупреждение времени компиляции на чистом Си, но, взглянув на этого монстра, урезал осетра. А нужно это было для следующего. Есть массив регистров с битами включения определенных параметров (любой из 32 бит можно установить в 1)

u32 REG[10];

 

Теперь идея заключалась в оптимизации количества доступов к этим регистрам: если нужно включить несколько параметров одновременно, то проще записать этот регистр с нужными битами сразу, а не по отдельности. Индекс нужного регистра и положение бита в нем определяются макросами

#define REGIND(x) ((x)/32) // индекс регистра в массиве
#define BITPOS(x) ((x)%32) // позиция бита в регистре

 

Вот и хотелось разом определять, входят ли указываемые номера параметров (номера бит [0 - 320]), например, [10, 17 и 28] или [13, 45, 46] в один физический регистр, и, если входят, сформировать одну инструкцию записи нужных бит в нужный регистр. Не в run-time, а на этапе компиляции.

 

В итоге, сделать это возможно, сравнивать нужно рассчитанные индексы регистров для каждого параметра. А, поскольку параметров может быть от 1 до 32 через запятую, нужно иметь 32 макроса, в каждом из которых проверяется от 1 до 32 входных параметров на равенство рассчитанных индексов в массиве регистров. Делать не стал (пока что).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, haker_fox сказал:

А не порекомендуете в контексте ещё хорошие книги по "крутому использованию" Си++11, 14, 17.

Мейерса плюсую. И ещё читал (вернее, в процессе) "Вандевурд Д., Джосаттис Н., Грегор Д. - Шаблоны C++. Справочник разработчика, 2-е издание - 2018". Это про шаблоны. Идёт туго, но очень интересно.

3 часа назад, ViKo сказал:

В main.cpp такой static_assert проходит. 

А когда пытаюсь использовать в шаблоне класса, выдается ошибка:

error:  #3673: function call must have a constant value in a constant expression
        static_assert(isEqual(g00, g01, g02, g03, g04, g05, g06, g07, 

К сожалению, у меня нет кейла, чтобы попробовать. Если вам не лень, попробуйте воспроизвести проблему (или её отсутствие) в онлайн-компиляторе. Если проблема воспроизведётся, то бросите сюда ссылку, и будем смотреть вместе.

Ну или попробуйте компилятор поновее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 16.08.2019 в 19:45, AHTOXA сказал:

Если вам не лень, попробуйте воспроизвести проблему (или её отсутствие) в онлайн-компиляторе. Если проблема воспроизведётся, то бросите сюда ссылку, и будем смотреть вместе.

Ну или попробуйте компилятор поновее.

Сложно в онлайн-компилятор занести, нужно нечто упрощенное сочинять.
Компилятор V6 выдает много ошибок в других местах. На него переходить не готов. Даже как-то дико выглядит, что 6-й отвергает то, что принимает 5-й. #pragma push, например.

Смысл ошибки такой. Задаю шаблонный класс порта из 16 отдельных пинов. Пины определены структурами, описывающими их режимы. 

template<
    uint g00, uint n00, Mode_td m00, Type_td t00, Speed_td s00, Pull_td p00, Altf_td a00,
    uint g01, uint n01, Mode_td m01, Type_td t01, Speed_td s01, Pull_td p01, Altf_td a01,
    uint g02, uint n02, Mode_td m02, Type_td t02, Speed_td s02, Pull_td p02, Altf_td a02,
    uint g03, uint n03, Mode_td m03, Type_td t03, Speed_td s03, Pull_td p03, Altf_td a03,
    uint g04, uint n04, Mode_td m04, Type_td t04, Speed_td s04, Pull_td p04, Altf_td a04,
    uint g05, uint n05, Mode_td m05, Type_td t05, Speed_td s05, Pull_td p05, Altf_td a05,
    uint g06, uint n06, Mode_td m06, Type_td t06, Speed_td s06, Pull_td p06, Altf_td a06,
    uint g07, uint n07, Mode_td m07, Type_td t07, Speed_td s07, Pull_td p07, Altf_td a07,
    uint g08, uint n08, Mode_td m08, Type_td t08, Speed_td s08, Pull_td p08, Altf_td a08,
    uint g09, uint n09, Mode_td m09, Type_td t09, Speed_td s09, Pull_td p09, Altf_td a09,
    uint g10, uint n10, Mode_td m10, Type_td t10, Speed_td s10, Pull_td p10, Altf_td a10,
    uint g11, uint n11, Mode_td m11, Type_td t11, Speed_td s11, Pull_td p11, Altf_td a11,
    uint g12, uint n12, Mode_td m12, Type_td t12, Speed_td s12, Pull_td p12, Altf_td a12,
    uint g13, uint n13, Mode_td m13, Type_td t13, Speed_td s13, Pull_td p13, Altf_td a13,
    uint g14, uint n14, Mode_td m14, Type_td t14, Speed_td s14, Pull_td p14, Altf_td a14,
    uint g15, uint n15, Mode_td m15, Type_td t15, Speed_td s15, Pull_td p15, Altf_td a15
>
class Port_cl
{
    static_assert(  g00 == g01 && g00 == g02 && g00 == g03 && g00 == g04 &&
                    g00 == g05 && g00 == g06 && g00 == g07 && g00 == g08 &&
                    g00 == g09 && g00 == g10 && g00 == g11 && g00 == g12 &&
                    g00 == g13 && g00 == g14 && g00 == g15, "The Port isn't the same!");
//    static_assert(isEqual(g00, g01, g02, g03, g04, g05, g06, g07,
//                          g08, g09, g10, g11, g12, g13, g14, g15), "The Port names are not equal!");

Эти режимы передаю в шаблон

using PortA = Port_cl<
    PPinsA.Pin00.gpio, PPinsA.Pin00.npin, PPinsA.Pin00.mode, PPinsA.Pin00.type, PPinsA.Pin00.speed, PPinsA.Pin00.pull, PPinsA.Pin00.altf,
    PPinsA.Pin01.gpio, PPinsA.Pin01.npin, PPinsA.Pin01.mode, PPinsA.Pin01.type, PPinsA.Pin01.speed, PPinsA.Pin01.pull, PPinsA.Pin01.altf,

Так вот на закомментированную проверку выдается ошибка:

error:  #3673: function call must have a constant value in a constant expression

даже если использую всего две константы

static_assert(isEqual(g00, g01), "Ups!");

Причем, если задам не одинаковые константы, то помимо показанной ошибки выдается ошибка, что константы не равны. Т.е. выполняется проверка.

error:  #2702: static assertion failed with "Ups!"

Изменено пользователем ViKo

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На сайте ARM:

[SDCOMP-28420]  In certain circumstances, when compiling with --cpp11, the compiler could incorrectly ignore a constexpr specifier resulting in one or more reports of Error: #28: expression must have a constant value or Error: #3673:function call must have a constant value in a constant expression. This has been fixed.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...