Tôi đã chơi xung quanh với auto
trong std::pair
. Trong đoạn mã dưới đây, hàm f
được cho là trả về một std::pair
loại phụ thuộc vào tham số mẫu.
Một ví dụ làm việc:
VÍ DỤ 1
template <unsigned S>
auto f()
{
if constexpr (S == 1)
return std::pair{1, 2}; // pair of ints
else if constexpr (S == 2)
return std::pair{1.0, 2.0}; // pair of doubles
else
return std::pair{0.0f, 0.0f}; // pair of floats
}
Điều này hoạt động với gcc 9.2, gcc 10.0, clang 9.0 và clang 10.0.
Tiếp theo, tôi muốn viết rõ ràng kiểu trả về như một std::pair
lý do rõ ràng:
VÍ DỤ 2
template <unsigned S>
std::pair<auto, auto> f()
{
if constexpr (S == 1)
return {1, 2};
/* ... */
}
Cả gcc 9.2 / 10.0 và clang 9.0 / 10.0 đều thất bại trong việc biên dịch này.
gcc 9,2
error: invalid use of 'auto'
error: template argument 1 is invalid // first argument (auto) of std::pair
error: template argument 2 is invalid // second argument (auto) of std::pair
error: cannot convert '<brace-enclosed initializer list>' to 'int' in return
Từ thông báo lỗi cuối cùng, gcc 9.2 dường như tin rằng đó std::pair<auto, auto>
là một int
. làm như thế nào để giải thích chuyện này?
gcc 10.0
error: returning initializer list
Lỗi này có thể hiểu được, tuy nhiên, tôi dự kiến hàm tạo std::pair
sẽ được gọi, hoặc có thiếu thứ gì ở đây không?
tiếng kêu 9.0 và 10.0
'auto' not allowed in template argument
excess elements in scalar initializer
no matching function for call to 'f'
Ok, clang không thích bất kỳ thứ gì trong số này. Từ thông báo lỗi thứ hai, dường như clang cũng tin rằng kiểu trả về là int
.
Cuối cùng, để sửa lỗi thu được bằng cách biên dịch với gcc 10.0, tôi quyết định trả lại một std::pair
cách rõ ràng:
VÍ DỤ 3
template <unsigned S>
std::pair<auto, auto> f()
{
if constexpr (S == 1)
return std::pair{1, 2};
/* ... */
}
tiếng kêu 9.0 và 10.0
Tương tự như trước đây, nhưng có thêm:
no viable conversion from returned value of type 'std::pair<int, int>' to function return type 'int'
Ở đây clang vẫn nghĩ rằng chúng tôi đang trở lại int
?
gcc 9,2
Giống như trước.
gcc 10.0
Nó hoạt động!
Tôi đoán một số tính năng vẫn phải được thực hiện, hoặc trong một trong các tình huống được mô tả ở trên, có trình biên dịch nào đúng và sai không? Theo tôi, ví dụ 2 nên hoạt động. Hay không nên?