gpt4 book ai didi

c++ - 构造一个对象以在其他地方按值返回

转载 作者:太空宇宙 更新时间:2023-11-04 13:31:57 25 4
gpt4 key购买 nike

在将 V8 JavaScript 引擎与 C++ 代码连接起来的包装器中,我想调用一个 C++ 函数,按值将对象传递给它。该对象是根据 JavaScript 中的数据自动构建的。

要调用的 C++ 函数采用 T 类型的对象,模板用于生成适配器函数 A,按值返回 T。问题是适配器函数 A 需要调用一个 JavaScript 函数,将另一个 C++ 函数 B 作为回调传递给它。 T 类型的对象是在那个函数 B 中构造的。它不能通过 JavaScript 返回给 A,A 不知道如何处理 T 类型的对象。

最简单的方法是在函数A中有一个T类型的局部变量。将指向它的指针赋给B,B为局部变量赋一个新值,A稍后返回,大致如此(一些细节省略关于如何将参数传递给 callJavaScript 和回调。实际上,T 的构造函数和 B 函数可能采用任意数量的更复杂的类型作为参数):

C++代码:

T A() {
T data;

callJavaScript("someJavaScriptFunction", &B, &data);

return data;
}

void B(T *data, int importantValue) {
*data = T(importantValue);
}

JavaScript 代码:

function someJavaScriptFunction(callback, dataRef) {
callback(dataRef, getImportantValueSomehow());
}

但是如果类型 T 不支持赋值甚至没有复制构造函数怎么办?有没有办法避免不必要的复制?我想在函数 A 中分配空白空间作为局部变量:

typename std::aligned_storage<sizeof(T), alignof(T)>::type data;

函数 B 然后可以使用 placement new 在该空间中构造对象,但是我如何使用移动语义从 A 返回结果对象?如何正确调用可能的析构函数?

我最终的想法是使用更多的模板技巧来为函数 A 中的类型 T 的构造函数分配参数空间,通过 B 中的指针设置它们并最终在 A 中构造对象,但如果某些参数中的数据丢失,它会变得令人讨厌callJavaScript 返回时超出范围。有解决方案吗?

编辑:所有这一切的目的是将 JavaScript 对象的内容放入 C++ 中。从 C++ 中读取对象的属性需要使用字符串按名称查找它们。 V8 中的 JIT 编译函数可以更直接地访问对象的字段,并且在 someJavaScriptFunction 中读取对象的属性会被编译为简单的指针读取。然后它可以使用各种参数调用 C++ 回调,这些参数可以相当快地从 JavaScript 值句柄转换为 C++ 类型。

EDIT2:第一个简单的想法是:

typename std::aligned_storage<sizeof(T), alignof(T)>::type data;
::new(&data) T(); // THIS LINE ACTUALLY PLACED IN ANOTHER FUNCTION
return(*reinterpret_cast<T *>(&data));

但我是否应该为在数据中构造的对象 T 调用析构函数,何时调用它,如何调用它?这是一个库,向返回值的接收者添加代码并不是真正的选择。

最佳答案

我不确定我是否完全理解您的问题,但您似乎不需要在函数中传递输出参数。

只需让函数 A 返回一个您已经在问题中提出的值,然后让 B 返回一个值。

由于“命名返回值优化”,不需要赋值运算符或复制构造函数。也就是说,如果您的代码满足“NRVO”的要求,您就可以了:

T B(int importantValue) { return T{importantValue}; }

不需要赋值运算符,也不需要从 T 复制构造函数。然后,将 callJavascript 更改为不需要输出参数,而是返回一个值,然后这将在没有复制构造函数或赋值运算符的情况下工作:

T A() { A rv{callJavascript(&B)}; return rv; }

一般来说,让你的函数不需要输出参数,否则你需要你的类型有复制构造函数和赋值运算符,或者违反类型系统。

顺便说一下,使 callJavascript 成为一个将可调用对象作为参数的模板。

关于c++ - 构造一个对象以在其他地方按值返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31077823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com