hkB*_*sai 7 c++ casting stdstring stdvector
我想调用一个库函数,其签名是:
bool WriteBinary(const std::vector<uint8_t> & DataToWrite);
Run Code Online (Sandbox Code Playgroud)
我有一个std::string变量,我想把它作为参数发送给它.
void WriteString(const std::string & TextData)
{
// ...
WriteBinary(TextData); // <-- How to make this line work?
// ...
}
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以直接发送std::string变量而无需复制它?
Mar*_*k B 11
没有办法做到这一点,因为两种类型的布局不能保证以任何方式相似.
最好的方法是修复WriteBinary使用"迭代器":
bool WriteBinary(const unsigned char* first, const unsigned char* last);
Run Code Online (Sandbox Code Playgroud)
或模板:
template <typename Iter>
bool WriteBinary(Iter first, Iter last);
Run Code Online (Sandbox Code Playgroud)
然后你可以将它用于字符串,向量或任何其他你喜欢的容器!
否则,您可以使用迭代器构造函数尽可能高效地执行复制:
WriteBinary(std::vector<uint8_t>(TextData.begin(), TextData.end()));
Run Code Online (Sandbox Code Playgroud)
我担心这是不可能的.既没有string也没有vector允许它"采用"预先存在的缓冲区的构造函数.并且它很可能是a string和a 的内存布局vector不同,所以没有可能的转换.
当然,您可以自由地破解自己以获得所需的结果。但是您应该准备好由同事或想要使用/维护/修改或移植您的代码的人进行摘要执行...
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;
}
Run Code Online (Sandbox Code Playgroud)
印刷
14 elements in vector!
HERE IS A TEST
HERE IS B TEST
Run Code Online (Sandbox Code Playgroud)
正如评论中正确提到的,该解决方案依赖于向量具有以下数据布局,并要求字符串连续存储其数据(不知道这是否是由标准预先确定的)。
template <typename T>
class vector
{
T* _first, _last, _end;
std::allocator<T> _alloc;
};
Run Code Online (Sandbox Code Playgroud)