1

我希望我的问题标题正确。

我有一个非常大/旧的数据库,其中包含许多非空终止字符数组和一些 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 犹豫不决。

4

2 回答 2

6

有不同的事情可以做。其中之一是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)具有适当大小的重载。

于 2013-01-16T21:34:14.397 回答
5

您可以更改第一个重载,以便不采用 std::string 引用,而是采用对您创建的具有从 std::string 的隐式转换的新类型的引用。所以你不会看到来自 const char* 的隐式转换,但会毫无问题地使用 std::string。

于 2013-01-16T21:20:35.020 回答