Bạn có thể làm điều này:
template <typename T, unsigned int N>
std::ostream & operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
này chỉ hoạt động cho mảng thời gian biên dịch, tất nhiên. Lưu ý rằng bạn không được phép tạo mẫu này khi T
là loại được tích hợp sẵn hoặc loại trong không gian tên std
!
Có lẽ tốt nhất để làm cho nội tuyến này nếu có thể, vì bạn sẽ gây ra một sự khởi tạo riêng biệt cho mỗi N
. (Ví dụ: pretty printer có ví dụ về điều này.)
Bạn sẽ thấy mẫu chăn giới thiệu một sự mơ hồ, vì os << "Hello"
hiện có hai lần quá tải: mẫu phù hợp với const char (&)[6]
và quá tải (không phải mẫu) decay-to-pointer const char *
, cả hai đều có trình tự chuyển đổi giống hệt nhau. Chúng ta có thể giải quyết điều này bằng cách vô hiệu hóa quá tải của chúng tôi đối với mảng char:
#include <ostream>
#include <type_traits>
template <typename T, unsigned int N>
typename std::enable_if<!std::is_same<T, char>::value, std::ostream &>::type
operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
Trong thực tế, để được thậm chí tổng quát hơn bạn cũng có thể làm cho basic_ostream
thông số mẫu tham số:
template <typename T, unsigned int N, typename CTy, typename CTr>
typename std::enable_if<!std::is_same<T, char>::value,
std::basic_ostream<CTy, CTr> &>::type
operator<<(std::basic_ostream<CTy, CTr> & os, const T (&arr)[N])
{
// ..
return os;
}
Theo quan điểm của thực tế là T
phải là loại do người dùng xác định, thậm chí bạn có thể thay thế is_same<T, char>
bằng is_fundamental<T>
để kiểm tra thêm một chút (nhưng người dùng vẫn không được sử dụng loại này cho mảng các loại thư viện chuẩn).
cảm ơn, nhưng tôi don 't hiểu lý do tại sao nó gây ra một instantiation riêng biệt cho mỗi N nếu không thực hiện nội tuyến? – Alcott
Vâng, đó là một mẫu, vì vậy mỗi mẫu thể hiện có thể kết thúc dưới dạng một hàm riêng biệt trong tệp nhị phân của bạn. Nếu bạn nội tuyến, bạn có thể có thể tránh được toàn bộ cuộc gọi hàm, mặc dù điều này là cuối cùng lên đến trình biên dịch. –
.Với toán tử << có 2 mẫu args, làm thế nào tôi có thể chỉ định arg N thứ hai? Rõ ràng tôi không thể chỉ đơn giản là sử dụng "cout << ar;", tôi có thể? – Alcott