Это, безусловно, ошибка в компиляторе Microsoft.
Вот одна большая разница в C и C ++.
e0 ? e1 : e2
В C ++ условное выражение создает lvalue , , если хотя бы одно из выражений во второй части (после '?'
) не является rvalue, тогда как в C условное выражение всегда выдает rvalue , несмотря ни на что. Это означает, что следующий код совершенно допустим в C ++, но это ошибка в C:
int a=10, b=20;
(a<b?a:b) = 100; //ok in C++, but error in C
В C ++ это не даст никакой ошибки, именно потому, что выражение (a<b?a:b)
является выражением lvalue, так что вы можете поместить его слева от присваивания.
Теперь вернемся к исходному вопросу. В вашем случае a
и b
являются массивами типа char (&) [6]
, а выражение a<b? a : b
должно выдавать lvalue, поскольку нет необходимости в преобразовании массив-указатель . Но в компиляторе Microsoft, кажется, есть преобразование массива в указатель .
Чтобы проверить это, можно написать это:
template <typename T, int N>
inline void f(T const (&a)[N]) {}
template <typename T>
inline T const& compare (T const& a, T const& b)
{
f(a < b ? b : a); //is the argument `char*` OR `char (&)[6]`?
return a < b ? b : a;
}
И это также дает без ошибок (в GCC), что означает, что выражение, которое вы передаете f()
, является массивом, а не указателем.