Mã sau đây biên dịch với Cộng đồng VS15 và in ra "Xin chào".Hành vi không mong muốn với bí danh loại mẫu trong VS2015
#include <functional>
#include <iostream>
template<typename T>
using void_template_alias_t = void;
template<typename T>
using Func = std::function<void(T)>;
template<typename T>
using FuncVoid = Func<void_template_alias_t<T>>;
int main()
{
FuncVoid<void> hello = [] { std::cout << "Hello\n"; };
hello();
}
Tôi nghĩ điều này không được phép biên dịch.
Tôi đang chơi xung quanh, mã phức tạp hơn một chút. Tôi ngây thơ mong đợi điều này để làm việc, nhưng đột nhiên nhận ra rằng mã này không nên biên dịch bởi vì bạn không thể thực hiện một Func<void>
(hoặc tôi là sai với điều này?).
- Tôi có tìm thấy giải pháp thay thế không?
- Đây có phải là hành vi mới từ tiêu chuẩn C++ 14 không?
- Hay đơn giản là lỗi trình biên dịch?
Chỉnh sửa: Phiên bản đơn giản hơn sau đây không biên dịch.
#include <functional>
#include <iostream>
template<typename T>
using Func = std::function<void(T)>;
int main()
{
Func<void> hello = [] { std::cout << "Hello\n"; };
hello();
}
- Vậy tại sao là mã trên biên dịch và làm việc như tôi lần đầu tiên dự kiến?
- Đây có phải là cách triển khai chính xác, nếu không, nó sẽ như thế nào?
Có một thế giới khác biệt giữa 'foo (void)' và 'sử dụng X = void; foo (X); '. Tôi sẽ ngạc nhiên nếu các trình biên dịch khác chấp nhận điều này. –
Ồ, tôi đã quá chắc chắn. Tiêu chuẩn nói rằng "Danh sách tham số' (void) 'tương đương với danh sách tham số trống.", Nhưng không xác định rằng '(void)' là văn bản theo nghĩa đen. Và không có sản xuất ngữ pháp đặc biệt nào cho nó, và cả g ++ và Visual C++ biên dịch 'void foo (X)' trong đó 'X' là tên của' void', và chúng biên dịch cuộc gọi 'foo()'. –
Có lẽ tôi nên chú ý rõ ràng hơn, rằng cách diễn giải trong đó '(void)' dùng để chỉ một hàm mà * type * của đối số đơn có hiệu lực 'void', và sau đó biểu thị một hàm không có đối số, không hoạt động tốt với mã mẫu gọi hàm với một đối số, nghĩa là nó không thực tế. Tuy nhiên, cả MSVC và MinGW g ++ đều chấp nhận 'foo (My_void)' không có khuôn mẫu và gọi 'foo()'. :( –