Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 非构造函数成员函数中的显式字符串行为_C++ - Fatal编程技术网

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

C++ 非构造函数成员函数中的显式字符串行为,c++,C++,我希望我的问题标题正确 我有一个非常大/旧的数据库,其中有许多以非null结尾的字符数组和一些std::string类型。我正在创建一个将使用此数据库的工具,我希望确保它对于非空终止字符数组的安全性。理想情况下,我希望支持这两种类型,以便于开发人员使用该工具 void AddCell( const std::string & _cell_str ); void AddCell( const char * _cell_data, size_t _array_size ); 但是,有一个特

我希望我的问题标题正确

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

void AddCell( const std::string & _cell_str );
void AddCell( const char * _cell_data, size_t _array_size );
但是,有一个特定的场景可能会出现问题:如果新开发人员不知道字符数组以非空结尾,并且出于懒惰,决定使用std::string的隐式转换,因为他不必输入数组大小,那么std::string可能会显示一些不需要的字符


我如何处理这个问题?我应该强制某人指定std::字符串的长度吗?我是否应该删除std::string重载函数,让每个人都从std::string中使用c_str?理想情况下,我只会使用explicit关键字,但它只对构造函数可用。我很犹豫是否要避免使用std::string。

您可以更改第一个重载,这样它就可以引用您创建的新类型,该类型具有std::string的隐式转换,而不是使用std::string引用。因此,您将看不到const char*的隐式转换,但将毫无问题地使用std::string。

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

可以执行不同的操作。其中之一是删除常量字符*重载:

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);
}

这允许使用AddCellMyCell,因为文字是一个数组,最好的候选者是模板,模板将依次分派到具有适当大小的const char*,size\u t重载。

可以执行不同的操作。其中之一是删除常量字符*重载:

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);
}

这允许使用AddCellMyCell,因为文字是一个数组,最好的候选者是模板,模板将以适当的大小分配给const char*,size\u t重载。

我这里缺少一些基本的东西。什么是std::string的隐式转换?您是指AddCellexample@ahenderson,std::string有一个构造函数,它接受char*并且不是显式的。@MarkRansom感谢您的澄清。我仍然希望我能有一个他们试图避免的行为的例子。这一点我现在很清楚了。如果有人在const char text[]处输入文本,那么我们就有UB,如果数组不是以null结尾的。我这里缺少一些基本的东西。什么是std::string的隐式转换?您是指AddCellexample@ahenderson,std::string有一个构造函数,它接受char*并且不是显式的。@MarkRansom感谢您的澄清。我仍然希望我能有一个他们试图避免的行为的例子。这一点我现在很清楚了。如果有人在const char text[]处输入文本,那么如果数组不是以null结尾的,我们就有UB。这种新类型还可以有一个构造函数,它接受一个char数组,并使用一些模板魔法自动包含数组大小。那么您只需要一个版本的成员函数。您能澄清一下从std::string隐式转换的含义吗?您的意思是它应该有一个接受const std::string引用的参数吗?那样的话,我不是还有现在这样的问题吗?它不应该是显式的吗?这种新类型还可以有一个构造函数,它接受一个char数组,并使用一些模板魔法自动包含数组大小。那么您只需要一个版本的成员函数。您能澄清一下从std::string隐式转换的含义吗?您的意思是它应该有一个接受const std::string引用的参数吗?那样的话,我不是还有现在这样的问题吗?这不应该是明确的吗?