非构造函数成员函数中的显式字符串行为

Explicit string behavior in non-constructor member functions

本文关键字:字符串 构造函数 成员 函数      更新时间:2023-10-16

希望我的题目写对了。

我有一个非常大/旧的数据库,其中有许多非null终止的字符数组和一些std::string类型。我正在创建一个工具,将使用这个数据库,我想确保它的安全性相对于非空终止字符数组。理想情况下,我希望支持这两种类型,使开发人员更容易使用该工具。

void AddCell( const std::string & _cell_str );
void AddCell( const char * _cell_data, size_t _array_size );

然而,有一个特定的场景可能会出现问题:如果一个新的开发人员没有意识到char数组是非空终止的,并且由于懒惰而决定使用std::string的隐式转换,因为他不需要输入数组大小,那么std::string可能会显示一些不需要的字符。

我该如何处理这个问题?我应该强制别人指定std::string的长度吗?我应该只是删除std::string重载函数,让每个人从他们的std::string使用c_str()吗?理想情况下,我只使用显式关键字,但它只适用于构造函数。我很犹豫是否要避免使用std::string.

可以做不同的事情。其中之一是delete -使const char*过载:

void AddCell(const std::string&);
void AddCell(const char*) = delete;
void AddCell(const char*,size_t);

将函数标记为delete会在使用时触发编译器错误,但不会将其从重载候选函数集中删除。如果用户传递一个const char*,第二个过载将被拾取,编译器将提示重载已被删除。

当然,您也可以为已知大小的数组提供包装器,以便它们可以安全无缝地传递字面量:
template <size_t N>
void AddCell(const char (&array)[N]) {
   AddCell(array, N);
}

这允许AddCell("MyCell"),因为字面量是一个数组,最好的候选者是模板,它将以适当的大小分配给(const char*,size_t)过载。

您可以更改第一个重载,使其不接受std::string引用,而是接受对您创建的新类型的引用,该类型具有从std::string的隐式转换。因此,您不会看到const char*的隐式转换,但会接受std::string,没有问题。