Подтвердить что ты не робот

Что такое оператор <? = "В С++?

Я встретил следующий код здесь, который является результатом реализации алгоритма Дейкстры с использованием С++ с использованием матрицы смежности.

//read in edges keeping only the minimum
for(int i=0; i<E; i++) {
    int v1,v2,tmp;
    fin >> v1; fin >> v2;
    fin >> tmp;
    adjmat[v1][v2]<?=tmp; // <?= sets left to min(left,right)
    adjmat[v2][v1]<?=tmp;
}

Обратите внимание на последние две строки, которые применяют оператор <?=. Как комментарий, следующая строка

adjmat[v1][v2]<?=tmp; // <?= sets left to min(left,right)

установит left в min(left,right).

Я никогда не видел этого оператора раньше. Я пробовал код в VS, он не может скомпилировать. Что это? Как установить left как min(left,right)?

4b9b3361

Ответ 1

Это старый расширение GCC; он делает то, что он говорит в комментарии (это составная форма назначения "минимального" оператора). Это не стандартный С++.

Разница между a = a < b ? a : b и a <?= b заключается в том, что последний только один раз оценивает каждый операнд.


В современном стандартном С++ я считаю, что вы могли бы написать алгоритм "назначить минимальный" следующим образом:

auto && __a = a;
auto && __b = b;
if (!(__a < __b)) { __a = std::forward<decltype(__b)>(__b); }

Это должно быть тело макроса, действие которого a <?= b, а a и b - произвольные выражения, потенциально связанные с побочными эффектами. Или вы можете обернуть его в шаблон:

template <typename T,
          typename U,
          typename P = std::less<std::common_type_t<std::decay_t<T>, std::decay_t<U>>>
T && clamp_to_minimum(T && a, U && b, P p = P())
{
    if (!(p(a, b))) { a = std::forward<U>(b); }
    return std::forward<T>(a);
}

Ответ 2

Это эквивалентно:

adjmat[v1][v2] = (adjmat[v1][v2]<tmp)? adjmat[v1][v2] : tmp;

В общем:

a OP ?= b; <= > a = (a OP b)? a : b;

Небольшой пример (скомпилированный с использованием MingW2.95 и C-Free IDE в Windows), показывающий, что сказал @Kerrek SB: расширение GCC расшифровывает операнды только один раз, что приятно

#include <stdio.h>

int f(int x)
{
    printf ("Calling f() with x=%d\n", x);
    return x*x;
}

int main()
{
    int a,b,c;

    printf ("A and B? ");
    scanf ("%d%d", &a, &b);

    c = a;
    a = (a<f(b))? a : f(b);
    printf ("A using ternary operator: %d\n", a);

    a = c;
    a <?= f(b);
    printf ("A using weird GCC extension: %d\n", a);

    return 0;
}


A and B? 3 1
Calling f() with x=1
Calling f() with x=1
A using ternary operator: 1
Calling f() with x=1
A using weird GCC extension: 1