Note that there are some explanatory texts on larger screens.

plurals
  1. POAre C++ non-type parameters to (function) templates ordered?
    primarykey
    data
    text
    <p>I am hosting <a href="http://developer.mozilla.org/En/SpiderMonkey/JSAPI_Reference" rel="nofollow noreferrer">SpiderMonkey</a> in a current project and would like to have template functions generate some of the simple property get/set methods, eg:</p> <pre><code>template &lt;typename TClassImpl, int32 TClassImpl::*mem&gt; JSBool JS_DLL_CALLBACK WriteProp(JSContext* cx, JSObject* obj, jsval id, jsval* vp) { if (TClassImpl* pImpl = (TClassImpl*)::JS_GetInstancePrivate(cx, obj, &amp;TClassImpl::s_JsClass, NULL)) return ::JS_ValueToInt32(cx, *vp, &amp;(pImpl-&gt;*mem)); return JS_FALSE; } </code></pre> <p>Used:</p> <pre><code>::JSPropertySpec Vec2::s_JsProps[] = { {"x", 1, JSPROP_PERMANENT, &amp;JsWrap::ReadProp&lt;Vec2, &amp;Vec2::x&gt;, &amp;JsWrap::WriteProp&lt;Vec2, &amp;Vec2::x&gt;}, {"y", 2, JSPROP_PERMANENT, &amp;JsWrap::ReadProp&lt;Vec2, &amp;Vec2::y&gt;, &amp;JsWrap::WriteProp&lt;Vec2, &amp;Vec2::y&gt;}, {0} }; </code></pre> <p>This works fine, however, if I add another member type:</p> <pre><code>template &lt;typename TClassImpl, JSObject* TClassImpl::*mem&gt; JSBool JS_DLL_CALLBACK WriteProp(JSContext* cx, JSObject* obj, jsval id, jsval* vp) { if (TClassImpl* pImpl = (TClassImpl*)::JS_GetInstancePrivate(cx, obj, &amp;TClassImpl::s_JsClass, NULL)) return ::JS_ValueToObject(cx, *vp, &amp;(pImpl-&gt;*mem)); return JS_FALSE; } </code></pre> <p>Then Visual C++ 9 attempts to use the JSObject* wrapper for int32 members!</p> <pre><code>1&gt;d:\projects\testing\jswnd\src\main.cpp(93) : error C2440: 'specialization' : cannot convert from 'int32 JsGlobal::Vec2::* ' to 'JSObject *JsGlobal::Vec2::* const ' 1&gt; Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast 1&gt;d:\projects\testing\jswnd\src\main.cpp(93) : error C2973: 'JsWrap::ReadProp' : invalid template argument 'int32 JsGlobal::Vec2::* ' 1&gt; d:\projects\testing\jswnd\src\wrap_js.h(64) : see declaration of 'JsWrap::ReadProp' 1&gt;d:\projects\testing\jswnd\src\main.cpp(93) : error C2440: 'initializing' : cannot convert from 'overloaded-function' to 'JSPropertyOp' 1&gt; None of the functions with this name in scope match the target type </code></pre> <p>Surprisingly, parening JSObject* incurs a parse error! (unexpected '('). This is probably a VC++ error (can anyone test that "template void foo() {}" compiles in GCC?). Same error with "typedef JSObject* PObject; ..., PObject TClassImpl::<em>mem>", void</em>, struct Undefined*, and double. Since the function usage is fully instantiated: "&amp;ReadProp", there should be no normal function overload semantics coming into play, it is a defined function at that point and gets priority over template functions. It seems the template ordering is failing here.</p> <p>Vec2 is just:</p> <pre><code>class Vec2 { public: int32 x, y; Vec2(JSContext* cx, JSObject* obj, uintN argc, jsval* argv); static ::JSClass s_JsClass; static ::JSPropertySpec s_JsProps[]; }; </code></pre> <p>JSPropertySpec is described in JSAPI link in OP, taken from header:</p> <pre><code>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; }; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload