Đây chắc chắn là lỗi trong trình biên dịch của Microsoft.
Dưới đây là một sự khác biệt lớn trong C và C++.
e0 ? e1 : e2
Trong C++, một condtional thể hiện sản xuất vế trái, trừ ít nhất một trong các biểu thức trong phần thứ hai (sau '?'
) là một rvalue, trong khi ở C, một conditional- biểu thức luôn tạo ra rvalue, bất kể là gì. Điều đó có nghĩa, các mã sau đây là hoàn toàn hợp lệ trong C++ nhưng nó là một lỗi trong C:
int a=10, b=20;
(a<b?a:b) = 100; //ok in C++, but error in C
Trong C++, nó sẽ không đưa ra bất cứ lỗi, chính vì sự biểu hiện (a<b?a:b)
là biểu hiện giá trị trái, như vậy là bạn có thể đặt nó ở phía bên trái của một bài tập.
Bây giờ, quay lại câu hỏi gốc. Trong trường hợp của bạn, a
và b
là các loại của char (&) [6]
và biểu thức a<b? a : b
sẽ tạo ra một giá trị, vì không cần chuyển đổi mảng thành con trỏ. Nhưng trong trình biên dịch của Microsoft, có vẻ như có chuyển đổi mảng thành con trỏ.
Để xác minh điều đó, người ta có thể viết này:
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;
}
Và nó mang lại cho no error một trong hai (trong GCC), có nghĩa là sự biểu hiện mà bạn vượt qua để f()
là một mảng, không phải là một con trỏ.
gcc [biên dịch] (http://ideone.com/WVU4h) mã này mà không gặp bất kỳ sự cố nào, vì vậy đây phải là lỗi trong MSVC. – Vlad
Dường như bạn không muốn chuyển chuỗi C vào mẫu như vậy (để so sánh địa chỉ của chúng). – UncleBens
Điều này trông giống như một lỗi, MSVC nói loại biểu thức 'a Praetorian