【问题标题】:C++ method as template parameterC++ 方法作为模板参数
【发布时间】:2016-04-24 00:40:30
【问题描述】:

我有一个函数类型,来自 SpiderMonkey:

typedef bool (* JSNative)(JSContext* cx, unsigned argc, JS::Value* vp);

我需要构造一个结构数组,其中包含对该类型方法的引用。

我需要使用带有参数的函数模板作为对某些类的方法的引用来制作这些。

我已经设法将类数据成员指针传递给这些模板:

template<typename PrivateType> class jsObjectDataClass : public jsBaseDataClass<PrivateType>
{
public:

template <typename pT, typename jspT, pT PrivateType::*Property> static bool GetProperty(JSContext *cx, unsigned argc, JS::Value *vp)
{
...
PrivateType* data = ...; // initialize here an object having the Property data member
...
data->*Property; // use here the Property data member of an object called 'data'
...
}

并将其用作:

const JSPropertySpec jsAIDocumentMiPrintRecord::fProperties[] = {
JS_PSGS("paperRect", (jsAIDocumentMiPrintRecord::GetProperty<AIRect, jsAIRect, &AIDocumentMiPrintRecord::paperRect>), (jsAIDocumentMiPrintRecord::SetProperty<AIRect, jsAIRect, &AIDocumentMiPrintRecord::paperRect>), JSPROP_PERMANENT | JSPROP_ENUMERATE),
...
JS_PS_END
};

它可以传递和获取集合对象的数据成员。

要恢复,请执行以下操作:

template <typename pT, typename jspT, pT PrivateType::*Property> static bool GetProperty(JSContext *cx, unsigned argc, JS::Value *vp)

变成:

jsAIDocumentMiPrintRecord::GetProperty<AIRect, jsAIRect, &AIDocumentMiPrintRecord::paperRect>(JSContext *cx, unsigned argc, JS::Value *vp)

匹配:

typedef bool (* JSNative)(JSContext* cx, unsigned argc, JS::Value* vp);

对于有限类型的方法而不是数据成员,我需要类似的东西(嗯,“有限”不是“少数”),这意味着一些方法,例如:

template <typename jsType, typename PrivateType, AIErr (SuiteType::*SuiteGetMethod)(PrivateType&)> static bool GetMethod(JSContext *cx, unsigned argc, JS::Value *vp)
    {
...

SuiteType* fSuite = ...; init the object that contains the method to be called

AIErr aiErr = kNoErr;

            PrivateType pt;

            if (fSuite)
                aiErr = fSuite->*SuiteGetMethod(pt); // call here the method of specific type
...
}

...但似乎这不匹配为:

typedef bool (* JSNative)(JSContext* cx, unsigned argc, JS::Value* vp);

用作:

const JSFunctionSpec jsAIDocumentSuite::fFunctions[] = {
JS_FN("GetDocumentFileSpecification", (jsAIDocumentSuite::GetMethod<jsAIFilePath, ai::FilePath, &AIDocumentSuite::GetDocumentFileSpecification>), 1, 0),
...
    JS_FS_END
};

我们在哪里:

struct AIDocumentSuite {

    /** Retrieves the file specification for the current document.
            @param file [out] A buffer in which to return the file specification.
        */
    AIAPI AIErr (*GetDocumentFileSpecification) ( ai::FilePath &file );
...
};

解决办法是什么?

谢谢。

【问题讨论】:

  • 错误是:Error C2440 'initializing' : cannot convert from 'overloaded-function' to 'JSNative'
  • 尝试通过引用传递该成员函数,并从 std::mem_fun_ref 获取它的引用(例如std::mem_fun_ref(&amp;myClass::myMethod)
  • 另见this
  • 我不知道该说什么,它是关于结构的数据成员,它们是指向函数的指针。我不能让它工作,或者我误解了这篇文章......
  • 您需要摆脱上述问题中的噪音。将其缩减为 sscce 或 mcve。看到这个stackoverflow.com/help/mcve——阅读并尝试一下。目标是删除不会直接导致编译错误的 EVERYTHING。并生成一小段代码来生成它。即使到"GetDocumentFileSpecification" 的值显然 也不会导致错误。删除所有垃圾。没有...,只是编译并生成错误的代码。但是是最小的。是的,这是工作。

标签: c++ templates methods parameters


【解决方案1】:

所以,解决办法是……

...模板函数和对方法的调用是:

template <typename jsType, typename PrivateType, AIErr(*SuiteType::*SuiteGetMethod)(PrivateType&)> static bool GetMethod(JSContext *cx, unsigned argc, JS::Value *vp)
{
...
SuiteType* fSuite = ...; init the object that contains the method to be called

AIErr aiErr = kNoErr;

PrivateType pt;

if (fSuite)
    aiErr = (fSuite->*SuiteGetMethod)(pt); // call here the method of specific type
...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多