【发布时间】:2017-12-30 13:14:36
【问题描述】:
我想将 c++ 引用传递给仅允许指针参数用于传递自定义数据的 c 样式 API。
在我的示例中,我只是将 c++ 引用的地址转换为指向 void 的指针(这发生在名为“function”的函数中)。这个指针被传递给一个 c 函数(称为“execute”),该函数也接受一个回调函数作为参数。在回调函数实现(名为“callback”)中,我将指向 void 的指针转换回指向 std::vector 的指针。
这在 MS Visual Studio 2017 中编译时没有警告和错误,并按预期运行(向量“v”包含从 1 到 5 的数字,它们也被打印出来) .但是我担心根据 C++ 标准这是否有效。
当然可以使用全局 std::vector 实例。但在某些情况下,比如我的情况,这可能是一个糟糕的解决方案。因为在我的情况下,每次调用“function”我都需要一个 std::vector 实例,因此不适合让一个全局实例替换参数。此外,全局实例在多线程环境中可能不合适,我想在每个线程的调用堆栈上保留 std::vector 的实例。用一个类包装 std::vector 实例并将指针传递给 std::vector 成员也不是我真正想要的。我很好奇我使用的具体实现的技术观点。
简而言之,我们会认为这个例子是一种不好的做法吗?将 Type 的引用地址转换为指向 void 的指针并从指向 void 的指针转换回指向 Type 的指针,同时忽略最初的指针是否有效是对类型的引用。有没有替代我上面描述的那些?
请在下面找到最小的工作示例:
#include <vector>
#include <iostream>
//
// The API of a 3rd party library (Typical C-Style Interface)
//
void execute(void (*callback)(void *, int[], int), void * context)
{
int data [5] = {1,2,3,4,5};
(*callback)(context, data, 5);
}
//
// My callback function fitting the signature for the 3rd party API
//
void callback(void * context, int data [], int size)
{
std::vector<int> * v = (std::vector<int> *)context;
for (int i = 0; i < size; i++) {
v->push_back(data[i]);
}
}
//
// Pass a reference to an std::vector as void * to the 3rd party API
//
void function(std::vector<int> & v)
{
execute(callback, (void *)&v);
}
//
// Pass a std::vector as reference to a function
//
// Evaluate the result at the end
//
int main()
{
std::vector<int> v;
function(v);
for (auto & e : v) {
std::cout << e << std::endl;
}
return 0;
}
【问题讨论】:
-
您不将“引用”传递给 C 风格的 API,您传递的是一个普通的旧指针(到 original 对象,
main函数中的向量v)。 -
&v的类型为std::vector<int>*- 指向向量的指针。你可以放弃(void*)演员,它也可以。 -
是的,我知道我没有通过“参考”。但我正在使用参考地址进行传递。这基本上是我要问的这个操作的有效性。
-
感谢您的回复。我更改了标题以更好地适应实际问题。
-
“在我的示例中,我只是将 c++ 引用转换为指向 void 的指针”。那是错误的,但这不是你正在做的。您将 C++ 引用的 address 转换为指向 void 的指针,这非常好。 (是的,这是真的,在底层,引用确实是一个指针,所以获取它的地址并没有真正做任何事情,但同样,这是正确的做法。)