2008-09-22 36 views
5

Tôi đang lưu trữ SpiderMonkey trong một dự án hiện tại và muốn có chức năng template tạo ra một số phương pháp get/set tài sản đơn giản, ví dụ:Có phải các tham số không kiểu C++ tới các mẫu (hàm) được đặt hàng không?

template <typename TClassImpl, int32 TClassImpl::*mem> 
JSBool JS_DLL_CALLBACK WriteProp(JSContext* cx, JSObject* obj, jsval id, jsval* vp) 
{ 
    if (TClassImpl* pImpl = (TClassImpl*)::JS_GetInstancePrivate(cx, obj, &TClassImpl::s_JsClass, NULL)) 
     return ::JS_ValueToInt32(cx, *vp, &(pImpl->*mem)); 
    return JS_FALSE; 
} 

sử dụng:

::JSPropertySpec Vec2::s_JsProps[] = { 
    {"x", 1, JSPROP_PERMANENT, &JsWrap::ReadProp<Vec2, &Vec2::x>, &JsWrap::WriteProp<Vec2, &Vec2::x>}, 
    {"y", 2, JSPROP_PERMANENT, &JsWrap::ReadProp<Vec2, &Vec2::y>, &JsWrap::WriteProp<Vec2, &Vec2::y>}, 
    {0} 
}; 

này hoạt động tốt, tuy nhiên, nếu tôi thêm một loại thành viên khác:

template <typename TClassImpl, JSObject* TClassImpl::*mem> 
JSBool JS_DLL_CALLBACK WriteProp(JSContext* cx, JSObject* obj, jsval id, jsval* vp) 
{ 
    if (TClassImpl* pImpl = (TClassImpl*)::JS_GetInstancePrivate(cx, obj, &TClassImpl::s_JsClass, NULL)) 
     return ::JS_ValueToObject(cx, *vp, &(pImpl->*mem)); 
    return JS_FALSE; 
} 

Sau đó Visual C++ 9 cố gắng sử dụng trình bao bọc JSObject * cho các thành viên int32!

1>d:\projects\testing\jswnd\src\main.cpp(93) : error C2440: 'specialization' : cannot convert from 'int32 JsGlobal::Vec2::* ' to 'JSObject *JsGlobal::Vec2::* const ' 
1>  Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast 
1>d:\projects\testing\jswnd\src\main.cpp(93) : error C2973: 'JsWrap::ReadProp' : invalid template argument 'int32 JsGlobal::Vec2::* ' 
1>  d:\projects\testing\jswnd\src\wrap_js.h(64) : see declaration of 'JsWrap::ReadProp' 
1>d:\projects\testing\jswnd\src\main.cpp(93) : error C2440: 'initializing' : cannot convert from 'overloaded-function' to 'JSPropertyOp' 
1>  None of the functions with this name in scope match the target type 

Đáng ngạc nhiên, việc nhả JSObject * phát sinh lỗi phân tích cú pháp! (bất ngờ '(') .Đây có thể là lỗi VC++ (bất kỳ ai có thể kiểm tra "template void foo() {}" biên dịch trong GCC?). Lỗi tương tự với "typedef JSObject * PObject; ..., PObject TClassImpl :: mem> ", void, struct Undefined *, và double. Kể từ khi sử dụng chức năng được khởi tạo đầy đủ:" & ReadProp ", sẽ không có hàm ngữ nghĩa quá tải bình thường vào chơi, nó là hàm được xác định tại điểm đó và được . ưu tiên hơn chức năng template có vẻ như mẫu đặt hàng được không đây

Vec2 chỉ là:.

class Vec2 
{ 
public: 
    int32 x, y; 

    Vec2(JSContext* cx, JSObject* obj, uintN argc, jsval* argv); 

    static ::JSClass s_JsClass; 
    static ::JSPropertySpec s_JsProps[]; 
}; 

JSPropertySpec được mô tả trong liên kết jsapi trong OP, lấy từ đầu er:

typedef JSBool 
(* JS_DLL_CALLBACK JSPropertyOp)(JSContext *cx, JSObject *obj, jsval id, 
           jsval *vp); 

... 

struct JSPropertySpec { 
    const char  *name; 
    int8   tinyid; 
    uint8   flags; 
    JSPropertyOp getter; 
    JSPropertyOp setter; 
}; 

Trả lời

3

Khá chắc chắn VC++ có "vấn đề" ở đây. Comeau và g ++ 4.2 đều hài lòng với chương trình sau đây:

struct X 
{ 
    int i; 
    void* p; 
}; 

template<int X::*P> 
void foo(X* t) 
{ 
    t->*P = 0; 
} 

template<void* X::*P> 
void foo(X* t) 
{ 
    t->*P = 0; 
} 

int main() 
{ 
    X x; 
    foo<&X::i>(&x); 
    foo<&X::p>(&x); 
} 

VC++ 2008SP1, tuy nhiên, là có ai trong số đó.

Tôi không có thời gian để đọc qua tiêu chuẩn của mình để tìm hiểu chính xác những gì ... nhưng tôi nghĩ VC++ là sai ở đây.

+0

Điều này có vẻ như: '( Bất cứ ai đặt một lỗi trong Connect chưa? –

+0

Tôi muốn đọc thông qua spec trước khi nộp hồ sơ này trong Connect. Tuy nhiên, tìm hiểu xem VC++ là sai từ thông số sẽ không nhỏ. Có thể đăng lên comp.whatever-it-is.C++ để xem một trong số họ có thể là luật sư ngôn ngữ và đăng chương và câu không? – DrPizza

+0

Vâng, tôi đã có nghĩa là nhìn thấy nếu đây là một vấn đề knowen (hóa ra nó là). Tiếng anh của tôi là xấu. https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=362170 –

0

Hãy thử thay đổi JSObject * thành loại con trỏ khác để xem liệu có tái tạo lỗi hay không. JSObject có được định nghĩa tại điểm sử dụng không? Ngoài ra, có thể JSObject * cần phải ở dạng parens.

+0

Không cần thêm parens nào nữa tại đây. Nó không giống như một con trỏ đến hàm thành viên; đây chỉ là một con trỏ đến thành viên. – DrPizza

0

Tôi chắc chắn không có guru mẫu, nhưng điều này có đun sôi xuống một trường hợp tinh tế của việc cố gắng phân biệt quá tải dựa hoàn toàn vào kiểu trả về không?

Vì C++ không cho phép quá tải các hàm dựa trên kiểu trả về, có lẽ điều tương tự cũng áp dụng cho tham số mẫu.

+0

Không, các hàm quá tải chỉ khác nhau theo các đối số mẫu được cho phép. – DrPizza

+0

Loại "int class: * member" là một con trỏ tới một thành viên int, không phải là hàm thành viên –

+0

Tất nhiên, không nên cố gắng suy nghĩ vào các ngày chủ nhật! Tôi nghĩ rằng nó đã thiếu một số dấu ngoặc đơn ... –

Các vấn đề liên quan