Xét đoạn mã sau:Tại sao tuyên bố này của một hàm trong lớp mẫu không hợp lệ?
template<int X, int Y>
struct S
{
typedef int func(int,float) const;
};
template<int X>
struct D : public S<X,6>
{
typename S<X,6>::func func;
};
template<int X>
int D<X>::func(int,float) const
{
return 1;
}
//----------------
struct W : public S<7,8>
{
S<7,8>::func func;
};
int W::func(int,float) const
{
return 2;
}
#include <iostream>
int main()
{
W w;
std::cout << w.func(1,4.3) << "\n";
D<3> d;
std::cout << d.func(1,4.3) << "\n";
}
Nếu tôi nhận xét ra mã khai báo lớp D
và D::func()
cũng như các dòng tương ứng trong main()
, mã biên dịch bình thường, và tôi thấy 2
trong đầu ra, như mong đợi.
Nhưng khi tôi làm cho lớp mẫu có nguồn gốc (thêm typename
trước khi khai báo hàm, như S<X.6>
là một phạm vi phụ thuộc), tôi nhận được các lỗi sau đây:
test.cpp:13:27: error: no ‘int D<X>::func(int, float) const’ member function declared in class ‘D<X>’
int D<X>::func(int,float) const
^
test.cpp: In instantiation of ‘struct D<3>’:
test.cpp:32:10: required from here
test.cpp:10:27: error: field ‘D<3>::func’ invalidly declared function type
typename S<X,6>::func func;
^
- Tại sao tôi không thể tuyên bố
func
trong một lớp mẫu có nguồn gốc, trong khi trong lớp không mẫu nó là OK? - Chính xác "loại chức năng được khai báo không hợp lệ" là gì? những gì không hợp lệ ở đây?
Tôi có cảm giác rằng điều này về mặt kỹ thuật hợp lệ bởi [dcl.fct]/10 trong thông số kỹ thuật, nhưng tuyên bố một hàm có typedef phụ thuộc giống như trường hợp góc của trường hợp góc: Tôi không chắc liệu có trình biên dịch nào hay không sẽ xử lý nó như bạn mong đợi. – TartanLlama
Tôi sẽ nói rằng 'S' có thể được chuyên biệt sau này, do đó, định nghĩa của 'D :: func' có thể trở thành không hợp lệ. –
Jarod42
@ Jarod42 Có vẻ như chúng ta cần 'function_typename' cũng như' typename': p – TartanLlama