gpt4 book ai didi

c++ - 通过采用迭代器的 C++ 函数包装采用原始指针的 C API

转载 作者:行者123 更新时间:2023-11-28 01:18:58 25 4
gpt4 key购买 nike

用带迭代器的函数包装带普通指针的 C API 的最佳方法是什么?

我正在尝试包装一个遗留 API,它采用指向连续内存的指针和大小。但是,在我的包装器中,我想提供一个基于迭代器的接口(interface)。

举个例子来说明问题:

// C-Api
bool socket_send(void* buffer, size_t size);

// C++ Wrapper
class Socket {
template <...>
bool send(Iterator begin, Iterator end) {
...
}
};

我想到的一个解决方案是创建一个 vector 并复制值:

class Socket {
template <...>
bool send(Iterator begin, Iterator end) {
std::vector<...> buff(begin, end);
socket_send(buffer.data(), buffer.size()*sizeof(decltype(buffer)::value_type);
}
};

这个解决方案的问题是数据的不必要拷贝,即使它已经是连续的内存。

围绕这个问题是否有通用且有效的解决方案?

最佳答案

对此没有通用的解决方案,因为迭代器不知道它们所表示的范围是否连续。只有指针(好吧,它们也是一种迭代器)知道这一点。此外,您的 C API 必须假定这一点。

因此,您提议的 Iterator 包装器的使用范围已经非常小。在任何有用的情况下,您的源数据(例如 vector )都已经有一种方法可以轻松获得指针和大小。在所有其他情况下,您都必须将数据复制到一个新的 vector 中,您已经正确地说这不是最佳的。

因此,您最好不这样做。现有的界面已经是它应该的样子了。

如果您已经有了 vector 迭代器,您可以像 socket_send((void*)&*begin, std::distance(begin, end)) 那样映射到 C 接口(interface)。您可以为这些(特别是 vector 迭代器)做一个转发重载,但这真的有什么意义吗? socket_send(vec.data(), vec.size()) 很好。

如果您确实需要接受任意范围,那么,好吧,复制您的拷贝。但请注意,该标准通常不为成本高昂的技术提供“自动”或“隐式”或“易于调用”的功能(例如,列表没有随机访问,因为那会很昂贵),并且我建议您采用相同的方法。


From C++20 we will have contiguous_iterator_tag ,您可以使用它来为不兼容的迭代器范围禁用通用接口(interface)。不过,我再次质疑它的实用性,因为在这种情况下,您已经在 C API 表单中获得了所需的信息。

关于c++ - 通过采用迭代器的 C++ 函数包装采用原始指针的 C API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57510623/

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