C++中的"<?="运算符是什么?

23

我在这里发现了下面的代码,它是使用邻接矩阵实现Dijkstra算法的C++实现。

//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)


10
多么愚蠢的代码。当你需要在紧随其后的注释中解释一个非标准的三字符运算符时,就是你停止使用它的时候了。 - Lightness Races in Orbit
2个回答

23
这是一个旧的GCC扩展,它执行注释中所说的操作(它是“最小”运算符的复合赋值形式)。这不是标准C ++。 a = a < b ? a : ba <?= b之间的区别在于后者只评估每个操作数一次。
在现代标准C ++中,我认为您可以像这样编写“分配最小值”的算法:
auto && __a = a;
auto && __b = b;
if (!(__a < __b)) { __a = std::forward<decltype(__b)>(__b); }

这应该是一个宏的主体,其效果为a <?= b,其中ab是任意表达式,可能具有副作用。或者您可以将其包装成模板:

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

我可以在Visual Studio (C++)中使用它吗?这是否意味着后者将更有效率? - herohuyongtao
@herohuyongtao:「这是GCC的扩展」听起来非常明确... - Jongware
@Jongware:嗯,它也可能是其他编译器的扩展,但我不知道。你总是可以想出一个等效的标准代码片段... - Kerrek SB
有没有其他关于这个运算符的更多信息可以找到? - herohuyongtao
@herohuyongtao:我添加了一个链接。我相信这已经从最近的GCC中删除了。 - Kerrek SB

7

这相当于:

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

一般来说:

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

下面是一个小例子(在 Windows 上使用 MingW2.95 和 C-Free IDE 编译)展示了 @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

条件运算符。 - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接