Tiêu chuẩn C++ 14.8.2 $ 7 cho biết:Làm thế nào để thay thế hoạt động trong khấu trừ đối số mẫu?
Sự thay thế xảy ra trong tất cả các loại và biểu thức được sử dụng trong kiểu hàm và khai báo tham số mẫu. Các biểu thức bao gồm không chỉ các biểu thức liên tục như các biểu thức xuất hiện trong mảng giới hạn hoặc như các đối số mẫu nontype mà còn biểu thức chung (tức là các biểu thức không liên tục) bên trong
sizeof
,decltype
và các ngữ cảnh khác cho phép các biểu thức không liên tục. Việc thay thế diễn ra theo thứ tự từ vựng và dừng lại khi gặp phải tình trạng khiến cho việc khấu trừ thất bại. [Lưu ý: Việc thay thế tương đương trong các đặc tả ngoại lệ chỉ được thực hiện khi đặc tả ngoại lệ được khởi tạo, tại thời điểm đó một chương trình bị hỏng nếu kết quả thay thế trong một loại hoặc biểu thức không hợp lệ. - cuối note]
Tiêu chuẩn cung cấp một ví dụ ở đây:
template <class T> struct A { using X = typename T::X; };
template <class T> typename T::X f(typename A<T>::X);
template <class T> void f(...) { }
template <class T> auto g(typename A<T>::X) -> typename T::X;
template <class T> void g(...) { }
void h() {
f<int>(0); // OK, substituting return type causes deduction to fail
g<int>(0); // error, substituting parameter type instantiates A<int>
}
Tại sao gọi g<int>(0)
là một lỗi ở đây? Không phải kiểu kết quả trả về lỗi T::X
gây ra sự cố thay thế? Sự khác biệt giữa chức năng mẫu f
và g
là gì?
Kiểu trả về là một phần của chữ ký hàm chứ không phải là tham số? – Barry
@Barry Tôi nghĩ cả kiểu trả về và tham số đều được coi là một phần của chữ ký chức năng – Carousel
@Barry Cả hai đều là một phần của chữ ký của mẫu chức năng, nhưng có lẽ tôi không nên sử dụng chữ ký ở đây. –