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

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

Так, как понимаете, не работает.

static_assert(g00 == g01 == g02, "Oh!");

Можно

static_assert(g00 == g01 && g01 == g02, "Oh!");

А еще как? А то их 16 штук, этих gXX... надоест сравнивать.

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

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


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

ну раз плюсы, то конечно завернуть в макросы :)

 

#define VA_ARGS_NUM_PRIV(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, Pn, ...) Pn
#define VA_ARGS_NUM(...) VA_ARGS_NUM_PRIV(-1, ##__VA_ARGS__, 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define COUNT(...) VA_ARGS_NUM(__VA_ARGS__)
 
#define ASSERT(COND,MSG) typedef char static_assert_##MSG[(COND)?1:-1]
 
#define ASSERT_EQ3(A,B,MSG) ASSERT(A==B,MSG)
#define ASSERT_EQ4(A,B,C,MSG) ASSERT(A==B&&B==C,MSG)
#define ASSERT_EQ5(A,B,C,D,MSG) ASSERT(A==B&&B==C&&C==D,MSG)
#define ASSERT_EQ6(A,B,C,D,E,MSG) ASSERT(A==B&&B==C&&C==D&&D==E,MSG)
 
#define CONCAT2(a,b) a##b
#define CONCAT(a,b) CONCAT2(a,b)
#define ASSERT_EQ(...) CONCAT(ASSERT_EQ,COUNT(__VA_ARGS__))(__VA_ARGS__)
 
int main(){
  ASSERT_EQ(1,1,1,1,1,ogh!); //ok
  ASSERT_EQ(1,1,4,1,ugh!); //assert
  return 0;
}


 

 

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

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


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

Первый аргумент static_assert вроде-как должен быть выражением из целочисленных констант времени компиляции. А у вас в заголовке темы вопрос про ПЕРЕМЕННЫЕ, которые на этапе компиляции ещё неизвестны - на то они и переменные. Уточните, что именно хотите проверять на равенство: константы времени компиляции или переменные. Если второе, то static_assert не подходит.

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


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

18 часов назад, ViKo сказал:

А еще как? А то их 16 штук, этих gXX... надоест сравнивать.

Так пойдёт?

template <typename T, typename... Types>
constexpr auto firstArg(T arg, Types... )
{
    return arg;
}

template <typename T, typename... Types>
constexpr auto isEqual(T arg, Types... args)
{
    if constexpr (sizeof...(args) > 1)
        return (isEqual(args...));
    if constexpr (sizeof...(args) > 0)
        return (arg == firstArg(args...));
    return true;
}

int main()
{
    static constexpr int a1 = 1;
    static constexpr int a2 = 1;
    static constexpr int a3 = 1;
    static_assert(isEqual(a1, a2, a3), "vars are not equal!");
}

ЗЫ. Вот здесь можно потыкать.

Изменено пользователем AHTOXA
Исправил код

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


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

Да, константы, известные при компиляции.

Однако, напрямую сравнить проще будет. 

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


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

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

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


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

Это я принадлежность выводов к одному порту GPIO так проверяю. Пытаюсь сделать шаблонный класс порта из отдельных выводов. 

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


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

19 hours ago, ViKo said:

А еще как? А то их 16 штук, этих gXX... надоест сравнивать.

 

Было когда-то понятие "сигнатурный анализ".

Можно вычислить такую сигнатуру, просто сложив по "модулю два" все константы, и сравнивать их с подобной сигнатурой, но уже входных переменных. Если сравнение сигнатур имеется, то, для убедительности, можно проверить и по-подробней. Если нет, то и сравнения нет. Это как бы увеличивает скорость. Здесь возможны вариации. 

 

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

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

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


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

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

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

Я прикидывал на эту тему, но просто не получается. Если пара констант отличается одинаково от остальных, то исключающее ИЛИ всех констант будет нулевым. Надо именно со сдвигами делать, как в псевдослучайной последовательности. Опять же, проще сравнить все константы с одной.

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


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

Какая вам разница, насколько оптимально будет выполнено сравнение? Оно же не в рантайме.
 

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


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

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

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

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

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

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

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

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

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

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