Tôi đã từ bỏ, xin vui lòng giúp giải thích hành vi này. Ví dụ tôi đưa ra bên dưới là ví dụ đơn giản nhất mà tôi có thể nghĩ ra, nhưng nó tóm tắt vấn đề (sử dụng g++4.9.2 trên Cygwin khi bật c++14). Tôi muốn tạo ra một hành vi tương tự như std::mem_fn
lớp học. Đây là lớp học của tôi:
mẫu
thuộc tính cấu trúc {
tĩnh R get(const T& t) {
return (t.*P)();
}
};
其中 R
là kiểu trả về,T
là loại đối tượng mà tôi quan tâm. Tham số mẫu thứ ba là một con trỏ tới hàm thành viên. Cho đến nay, rất tốt.
Sau đó, tôi tạo một lớp đơn giản chứa số nguyên như bên dưới
lớp dữ liệu_class {
public:
chưa ký get_data() const {
trả về m_data;
}
private:
m_data không dấu;
};
Đây là những gì sẽ được hiển thị trước đó tài sản
Lớp được sử dụng trong lớp.
Bây giờ tôi tạo hai kế thừa từ lớp dữ liệu
lớp, như được hiển thị dưới đây
cấu trúc my_classA
: dữ liệu công khai_class {
sử dụng data = property;
};
// giống như my_classA, chỉ được tạo khuôn mẫu
mẫu
cấu trúc my_classB
: dữ liệu công khai_class {
sử dụng data = property;
};
Chúng có cùng typedef bên trong, nhưng my_classB
Nó được tạo khuôn mẫu. Bây giờ các loại sau đây về mặt lý thuyết sẽ giống nhau:
sử dụng target_t = property;
sử dụng test1_t = typename my_classA::data;
sử dụng test2_t = typename my_classB<1>::data;
Nhưng trình biên dịch của tôi chỉ nói kiểm tra1_t
Và mục tiêu_t
là như nhau. kiểm tra2_t
Loại suy luận rõ ràng là
thuộc tính>
Loại này có các dấu ngoặc vuông xung quanh các con trỏ tới các hàm thành viên. Tại sao kiểm tra2_t
Và mục tiêu_t
không giống nhau à? Nếu bạn muốn dùng thử trên hệ thống của mình, đây là mã hoàn chỉnh. Bất kỳ trợ giúp được đánh giá rất cao.
#include
lớp dữ liệu_class {
public:
chưa ký get_data() const {
trả về m_data;
}
private:
m_data không dấu;
};
//lấy kiểu trả về, kiểu lớp và một con trỏ tới hàm thành viên
//hàm get lấy một đối tượng làm đối số và sử dụng con trỏ trên để gọi hàm thành viên
mẫu
thuộc tính cấu trúc {
tĩnh R get(const T& t) {
return (t.*P)();
}
};
cấu trúc my_classA
: dữ liệu công khai_class {
sử dụng data = property;
};
// giống như my_classA, chỉ được tạo khuôn mẫu
mẫu
cấu trúc my_classB
: dữ liệu công khai_class {
sử dụng data = property;
};
//dùng để tạo ra lỗi thông tin
mẫu
cấu trúc what_is;
// về lý thuyết thì cả 3 loại dưới đây đều giống nhau
//nhưng g++ nói rằng test2_t thì khác
sử dụng target_t = property;
sử dụng test1_t = typename my_classA::data;
sử dụng test2_t = typename my_classB<1>::data;
static_assert(std::is_same::value, ""); //điều này đã vượt qua
static_assert(std::is_same::value, ""); // điều này không
int chính() {
what_is t1;
what_is t2;
}
Tôi đã chạy mã của bạn bằng c++11 vì tôi chưa quen lắm với c++14. Nhưng tất cả những gì tôi thay thế là sử dụng (bí danh) và typedef và đơn giản hóa mã một chút. Không ảnh hưởng đến đầu ra của nó.
Tôi đã nhận được kết quả như mong đợi bằng cách thêm tên loại T vào mẫu classB được kế thừa, khi được khởi tạo sẽ thay thế R bằng T, vì vậy "không dấu" trong trường hợp này.
#include
#include
mẫu
thuộc tính cấu trúc
{
tĩnh R get(const T& t)
{
return (t.*P)();
}
};
cấu trúc data_class
{
private:
m_data không dấu;
public:
unsigned get_data() const
{
trả về m_data;
}
};
struct my_classA : dữ liệu công khai_class
{
thuộc tính typedef data;
};
mẫu
struct my_classB : dữ liệu công khai_class
{
thuộc tính typedef dữ liệu;
};
int main()
{
typedef tên kiểu my_classA::data NormClassA;
tên kiểu typedef my_classB::data tmplClassB;
std::cout<< std::is_same< property , NormClassA >::value <<>
std::cout<< std::is_same< property , tmplClassB >::value <<>
}
Kết quả là thế này:
~$g++ -std=c++11 test.cpp
~$./a.out
1
1
Tôi nghĩ vấn đề có liên quan đến tiêu chuẩn khởi tạo mẫu lớp vì khi tôi cố in sizeof của cả hai lớp lần đầu, my_classA::data trả về 1 nhưng my_classB<1>::data lại gặp lỗi trình biên dịch. đang xảy ra Tình trạng này vẫn còn rất mơ hồ đối với tôi. Về mặt kỹ thuật, lẽ ra nó phải khởi tạo mẫu lớp tốt. Có lẽ các thuộc tính trong mẫu classB đã được khởi tạo không chính xác. Tôi sẽ nghiên cứu thêm về vấn đề này, nhưng nếu bạn tìm thấy câu trả lời, vui lòng đăng nó. Đây là một điều thú vị!
EDIT: Mã gốc chạy tốt trên Cygwin GCC 4.8.2. Kết quả là 1 và 1. Nó có thể chỉ là một vấn đề với trình biên dịch gcc4.9.2.
Tôi là một lập trình viên xuất sắc, rất giỏi!