Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's "<?=" operator in C++? [duplicate]

I came across the following code here, which is from the C++ implementation of Dijkstra algorithm using an adjacency matrix.

//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;
}

Pay attention to the last two lines, which apply operator <?=. As being commented, the following line

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

will set left to min(left,right).

I never see this operator before. I tried the code in VS, it can not compile. What is it? How can it set left to be min(left,right)?

like image 927
herohuyongtao Avatar asked Dec 28 '13 12:12

herohuyongtao


People also ask

Is += different from =+ in C?

In modern C, or even moderately ancient C, += is a compound assignment operator, and =+ is parsed as two separate tokens.

What is the == operator in C?

Equal To Operator (==) == is an Equal To Operator in C and C++ only, It is Binary Operator which operates on two operands. == compares value of left and side expressions, return 1 if they are equal other will it will return 0.

Is there a += in C?

C programming has two operators increment ++ and decrement -- to change the value of an operand (constant or variable) by 1. Increment ++ increases the value by 1 whereas decrement -- decreases the value by 1. These two operators are unary operators, meaning they only operate on a single operand.

What is a copy assignment operator?

A copy assignment operator of class T is a non-template non-static member function with the name operator= that takes exactly one parameter of type T, T&, const T&, volatile T&, or const volatile T&. For a type to be CopyAssignable, it must have a public copy assignment operator.

What is the use of ?? operator in C?

?? Operator (C# Reference) The ?? operator is called the null-coalescing operator and is used to define a default value for a nullable value types as well as reference types. It returns the left-hand operand if it is not null; otherwise it returns the right operand.

What is the difference between arithmetic and operator in C?

An operator is a symbol that operates on a value or a variable. For example: + is an operator to perform addition. C has a wide range of operators to perform various operations. An arithmetic operator performs mathematical operations such as addition, subtraction, multiplication, division etc on numerical values (constants and variables).

What are operators in programming language?

Operators are the foundation of any programming language. We can define operators as symbols that help us to perform specific mathematical and logical computations on operands. In other words, we can say that an operator operates the operands.

What are the assignment operators in C language?

The table below lists all the assignment operators supported by the C language: Used to assign the values from right side of the operands to left side of the operand. Adds the value of the right operand to the value of the left operand and assigns the result to the left operand.


2 Answers

It is an old GCC extension; it does what it says in the comment (it's the compound assignment form of the "minimum" operator). This is not standard C++.

The difference between a = a < b ? a : b and a <?= b is that the latter only evaluates each operand once.


In modern standard C++, I believe you could write an "assign the minimum" algorithm like this:

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

This should be the body of a macro which has the effect of a <?= b, and a and b are arbitrary expressions, potentially with side effects. Or you could wrap it into a template:

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);
}
like image 172
Kerrek SB Avatar answered Oct 11 '22 16:10

Kerrek SB


It is equivalent to:

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

In general:

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

A little example (compiled using MingW2.95 and C-Free IDE on Windows) showing what @Kerrek SB said: the GCC extension evalute operands only once, which it's nice

#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
like image 7
mcleod_ideafix Avatar answered Oct 11 '22 17:10

mcleod_ideafix