Vấn đề thực sự là một sự mơ hồ trong một chuyên môn hóa từng phần:
Bên trong, bộ cấp phát sử dụng một số lập trình meta (_Ptr_cat
) để xác định xem dtor là được kêu gọi các phần tử của vector (hoặc không làm gì cả). Metaprogramming này cố gắng phân biệt một số trường hợp bằng cách sử dụng một phần chuyên môn hóa. _Ptr_cat
sử dụng _Ptr_cat_helper
đang được chuyên biệt về loại con trỏ của người cấp phát vector - số value_type
của vectơ là TPointer const* == const float (*)[3]
, do đó trình phân bổ vectơ có kiểu con trỏ const float(**)[3]
.
Khi bạn sử dụng std::vector < const float(*)[3] >
, thông báo lỗi chứa phần [3]
, trong khi sử dụng std::vector < TPoint const* >
, các [3]
không được hiển thị o.o
_Ptr_cat
hy vọng hai đối số mẫu cùng loại với khả năng khác nhau c-vòng loại, ví dụ float*, float const*
. Bây giờ, hai loại đầu vào là cả hai const float (**)[3]
. MSVC giải quyết chúng một cách mơ hồ cho các chuyên ngành của _Ptr_cat_helper
: Ty**, Ty const**
và/hoặc Ty**, Ty**
. Tôi đã xác minh rằng bằng cách viết một ví dụ nhỏ bắt chước chuyên môn từng phần của _Ptr_cat_helper
(chỉ các mẫu đơn thuần, không có tham chiếu STd Lib).
Tuy nhiên, tôi không thể giải thích tại sao điều này xảy ra. Kỳ lạ thay, không có sự mơ hồ khi thiết lập một ví dụ chỉ sử dụng một thông số chuyên môn - const float(**)[3]
được giải quyết thành Ty const**
với Ty = float const[3]
như mong đợi.
Cảm ơn Peter Alexander, tôi cũng đã thử ví dụ đơn giản của tôi (2 tham số mẫu) với g ++, và nó hoạt động như mong đợi, không mơ hồ. Có lẽ điều này có thể là một vấn đề trình biên dịch?
Hãy để tôi đề xuất một số biện pháp khắc phục:
- Nếu bạn thực sự muốn thay đổi các lib chuẩn MSVC, bạn có thể thêm một chuyên môn hóa
_Ptr_cat_helper < const Ty (**)[3], const Ty (**)[3] >
mà phù hợp chính xác và giải quyết sự mơ hồ. Thật không may, bạn phải cung cấp kích thước một cách rõ ràng (3).
- Không sử dụng mảng tại đây. Sử dụng
std::array
(có sẵn trong tr1
trong VS08) hoặc cấu trúc hoặc gợi ý đơn giản (float const*
thay vì float const[3]
)
sử dụng một wrapper đơn giản:
template < typename T > struct wrapper { T wrapped; }
std::vector < wrapper <TPoint> const* > m;
hoạt động tốt đối với tôi.
Edit: đây là ví dụ tôi sử dụng:
#include <typeinfo>
#include <iostream>
template < typename T1, typename T2 >
struct Spec
{
static const char* check() { return "plain"; }
typedef void Value;
};
#define MAKE_SPEC(ARG0, ARG1) \
template < typename T > \
struct Spec < ARG0, ARG1 > \
{ \
static const char* check() { return #ARG0 ", " #ARG1; } \
typedef T Value; \
}
MAKE_SPEC(T**, T**);
MAKE_SPEC(T**, T const**);
// can do more, but need not to..
int main()
{
typedef Spec < const float(**)[3], const float(**)[3] > MySpec;
std::cout << MySpec::check() << " -- " << typeid(MySpec :: Value).name();
}
Đừng có VS cài đặt trước mặt tôi, nhưng nó hoạt động với GCC. Bạn có thể đã tìm thấy một lỗi trong lib chuẩn của họ. –
Nâng cấp VS hiện không khả thi: chúng tôi phụ thuộc vào dll (sử dụng các thành phần MFC) từ các nhóm khác ... Nhưng sẽ rất tuyệt khi biết nếu ba dòng trên biên dịch trên VS2010 – coproc
Xin lỗi, nó không biên dịch, đó là lý do tại sao tôi đã xóa nhận xét đó. Tuy nhiên, hoàn toàn không rõ nguyên tố của vec tơ là gì. Một con trỏ đến một mảng của ba yếu tố của const nổi? – Xeo