Des paramètres non typés C ++ sont-ils commandés pour les modèles (de fonction)?

StackOverflow https://stackoverflow.com/questions/112612

  •  02-07-2019
  •  | 
  •  

Question

J'héberge un SpiderMonkey dans un projet en cours et souhaite disposer de fonctions de modèle. générer certaines méthodes simples de la propriété get / set, par exemple:

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;
}

Utilisé:

::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}
};

Cela fonctionne bien, cependant, si j'ajoute un autre type de membre:

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;
}

Ensuite, Visual C ++ 9 tente d'utiliser le wrapper JSObject * pour les membres 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

Étonnamment, l'analyse de JSObject * entraîne une erreur d'analyse! (inattendu '('). C’est probablement une erreur de VC ++ (quelqu'un peut-il tester que le "template void foo () {}" est compilé dans GCC?). Même erreur avec "typedef JSObject * PObject; ..., PObject TClassImpl :: mem > ", void , struct Undefined *, and double. Puisque l'utilisation de la fonction est totalement instanciée:" & ReadProp ", il ne devrait pas y avoir de sémantique de surcharge de fonction normale , c’est une fonction définie à ce stade et a la priorité sur les fonctions de modèle. Il semble que la commande de modèle échoue ici.

Vec2 est juste:

class Vec2
{
public:
    int32 x, y;

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

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

JSPropertySpec est décrit dans le lien JSAPI dans OP, extrait de l'en-tête:

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;
};
Était-ce utile?

La solution

Il est pratiquement certain que VC ++ a " issues " ici. Comeau et g ++ 4.2 sont satisfaits du programme suivant:

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, cependant, n'en possède aucun.

Je n'ai pas le temps de lire mon standard pour savoir exactement ce que c'est ... mais je pense que VC ++ est dans l'erreur ici.

Autres conseils

Essayez de remplacer JSObject * par un autre type de pointeur pour voir si cela reproduit l'erreur. Est-ce que JSObject est défini au point d'utilisation? En outre, peut-être que JSObject * doit être par deux.

Je ne suis certes pas un gourou des modèles, mais cela revient-il à tenter de différencier les surcharges uniquement en fonction du type de retour?

Etant donné que C ++ n'autorise pas la surcharge de fonctions basées sur le type de retour, la même chose s'applique aux paramètres de modèle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top