我想调用一个库函数,其签名是:
bool WriteBinary(const std::vector<uint8_t> & DataToWrite);
我有一个std::string
变量,我想将此函数作为参数发送。
void WriteString(const std::string & TextData)
{
// ...
WriteBinary(TextData); // <-- How to make this line work?
// ...
}
有没有办法直接发送std::string
变量而不复制它?
答案 0 :(得分:11)
没有办法做到这一点,因为这两种类型的布局不能保证在任何方面都相似。
最好的方法是修复WriteBinary
而不是使用“迭代器”:
bool WriteBinary(const unsigned char* first, const unsigned char* last);
或模板化:
template <typename Iter>
bool WriteBinary(Iter first, Iter last);
然后你可以将它用于字符串,向量或任何其他你喜欢的容器!
否则,您可以使用迭代器构造函数尽可能高效地执行复制:
WriteBinary(std::vector<uint8_t>(TextData.begin(), TextData.end()));
答案 1 :(得分:5)
我担心这是不可能的。 string
和vector
都没有构造函数可以“采用”预先存在的缓冲区。并且string
和vector
的内存布局很可能不同,因此无法进行转换。
答案 2 :(得分:2)
有没有办法可以直接发送std :: string变量而不用 制作它的副本?
不,当然不安全。
如果您可以控制库,我建议稍微重构一下。
添加:
template<typename CharT>
void WriteBinary(CharT const* buffer, size_t count);
或者:
template<typename FwdIter>
void WriteBinary(FwdIter begin, FwdIter end);
然后让现有的WriteBinary
和WriteString
调用它:
void WriteBinary(std::vector<uint8_t> const& vec)
{ WriteBinary(&*vec.begin(), vec.size()); }
void WriteString(std::string const& s)
{ WriteBinary(&*s.begin(), s.size()); }
或者:
void WriteBinary(std::vector<uint8_t> const& vec)
{ WriteBinary(vec.begin(), vec.end()); }
void WriteString(std::string const& s)
{ WriteBinary(s.begin(), s.end()); }
就个人而言,我更喜欢基于迭代器的方法。感觉“更干净”。
(注意:对于指针/大小方法,您可能希望检查是否为空。如果您在空向量/字符串上推导begin()
的结果,某些实现可能会断言。)
答案 3 :(得分:1)
你当然可以自由地通过自己来获得所需的结果。 但是您应该为同事或想要使用/维护/修改或移植代码的人准备摘要执行...
int main (void)
{
std::string teststring("HERE IS A TEST");
char * p = (char*)malloc(3*sizeof(char*) + sizeof(std::allocator<char>));
std::allocator< std::allocator<char> > alloc_alloc;
char * pa = p + 3*sizeof(char*);
alloc_alloc.construct((std::allocator<char>*)pa);
char const * cp = teststring.data();
char const * * vec_it = (char const**)p;
vec_it[0] = cp;
vec_it[1] = cp + teststring.length();
vec_it[2] = vec_it[1];
std::vector<char> &a_vector = *((std::vector<char, std::allocator<char>>*)p);
cout << a_vector.size() << " elements in vector!" << endl;
for (std::vector<char>::iterator i=a_vector.begin(); i!=a_vector.end(); ++i)
{
cout << *i;
}
cout << endl;
// set char 8 to 66 = B
a_vector[8] = 66;
cout << teststring << endl;
}
打印
14 elements in vector!
HERE IS A TEST
HERE IS B TEST
正如评论中正确提到的,此解决方案依赖于向量具有以下数据布局,并且需要字符串连续存储它的数据(不管这是否由标准预先确定)。
template <typename T>
class vector
{
T* _first, _last, _end;
std::allocator<T> _alloc;
};