Estoy recibiendo SpiderMonkey en un proyecto actual y me gustaría tener funciones de plantilla generan algunos de los métodos get/set sencilla de propiedad, por ejemplo:¿Están pedidos los parámetros C++ no de tipo para (función)?
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;
}
usados:
::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}
};
Esto funciona bien, Sin embargo, si añado otro tipo de miembro:
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;
}
a continuación, Visual C++ 9 intentos de utilizar la JSObject * envoltorio para los miembros 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
Sorprendentemente, parening JSObject * incurre en un error de análisis! (inesperado '('). Este es probablemente un error de VC++ (¿alguien puede probar que "template void foo() {}" compila en GCC?). Mismo error con "typedef JSObject * PObject; ..., PObject TClassImpl :: mem> ", void, struct Undefined * y double. Como el uso de la función está completamente instanciado:" & ReadProp ", no debería haber una semántica de sobrecarga de función normal que entra en juego, es una función definida en ese punto y obtiene . prioridad sobre las funciones de plantilla parece el ordenamiento plantilla está fallando aquí
Vec2 es simplemente:.
class Vec2
{
public:
int32 x, y;
Vec2(JSContext* cx, JSObject* obj, uintN argc, jsval* argv);
static ::JSClass s_JsClass;
static ::JSPropertySpec s_JsProps[];
};
JSPropertySpec se describe en el enlace JSAPI en OP, tomada desde la cabeza 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;
};
Esto parece probable: '( ¿Alguien ha puesto un error en Connect todavía? –
Me gustaría leer las especificaciones antes de archivar esto en Connect. Sin embargo, averiguar si VC++ está equivocado de la especificación no será trivial. Posiblemente publique en comp.whatever-it-is.C++ para ver si uno de ellos puede subir de categoría y publicar un capítulo y un versículo? – DrPizza
Bueno, quería ver si esto es un problema conocido (resulta que sí lo es). Mi inglés es el malo. https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=362170 –