Baj*_*ile 0 c++ casting std stdstring c++11
我喜欢了解赞成与反对者拥有和不拥有这样的演员。在包括Stack Overflow在内的多个地方,我可以看到const char*强制转换被认为是一个坏主意,但我不确定为什么吗?
编写通用例程和模板时,缺少(const char*)和强制始终使用强制转换c_str()会产生一些问题。
void CheckStr(const char* s)
{
}
int main()
{
std::string s = "Hello World!";
// all below will not compile with
// Error: No suitable conversion function from "std::string" to "const char *" exists!
//CheckStr(s);
//CheckStr((const char*)s);
// strlen(s);
// the only way that works
CheckStr(s.c_str());
size_t n = strlen(s.c_str());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
例如,如果我有大量接受const char*输入的文本处理功能,并且我希望std::string每次使用都能够使用c_str()。但是以这种方式std::string,const char*如果没有额外的努力,模板函数就不能同时使用。
作为一个问题,我可以看到一些运算符重载问题,但可以解决这些问题。
例如,正如[eerorika]指出的那样,通过允许隐式强制转换为指针,我们允许将非自愿的字符串类包含在布尔表达式中。但是我们可以通过删除bool运算符轻松解决此问题。更进一步,强制转换操作符必须明确:
class String
{
public:
String() {}
String(const char* s) { m_str = s; }
const char* str() const { return m_str.c_str(); }
char* str() { return &m_str[0]; }
char operator[](int pos) const { return m_str[pos]; }
char& operator[](int pos) { return m_str[pos]; }
explicit operator const char*() const { return str(); } // cast operator
operator bool() const = delete;
protected:
std::string m_str;
};
int main()
{
String s = "Hello";
string s2 = "Hello";
if(s) // will not compile: it is a deleted function
{
cout << "Bool is allowed " << endl;
}
CheckStr((const char*)s);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我喜欢了解赞成与反对者拥有和不拥有这样的演员。
缺点:隐式转换通常具有令程序员惊讶的行为。
例如,您对以下程序会有什么期望?
std::string some_string = "";
if (some_string)
std::cout << "true";
else
std::cout << "false";
Run Code Online (Sandbox Code Playgroud)
程序是否应格式错误,因为std::string没有转换为bool?结果应该取决于字符串的内容吗?大多数程序员会有相同的期望吗?
使用current std::string,由于没有这样的转换,因此上述内容将格式错误。很好 不管程序员期望什么,他们在尝试编译时都会发现自己的误解。
如果std::string对指针进行了转换,那么还将存在一个转换序列,以通过对指针的转换来实现转换。上面的程序格式正确。并且程序将打印true而不管字符串的内容如何,因为c_str它永远不会为null。如果程序员反而希望空字符串为假,该怎么办?如果他们既不想使用任何行为,又无意间在其中使用了字符串怎么办?
接下来的程序呢?
std::string some_string = "";
std::cout << some_string + 42;
Run Code Online (Sandbox Code Playgroud)
您是否希望该程序格式错误,因为没有用于string和的运算符int?
如果存在对的隐式转换char*,则以上内容将具有未定义的行为,因为它执行指针算术并访问其边界之外的字符串缓冲区。
Run Code Online (Sandbox Code Playgroud)// all below will not compile with strlen(s);
这实际上是一件好事。大多数情况下,您不想打电话strlen(s)。通常,应该使用s.size()它,因为它渐近地更快。对需求的需求strlen(s.c_str())如此之少,以至于冗长的一点点微不足道。
强制使用.c_str()之所以很棒,是因为它向程序的读者显示,它不是std::string传递给函数/运算符的,而是传递给的char*。使用隐式转换时,不可能将一个与另一个区分开。
在编写通用例程和模板时会产生一些问题。
这样的问题不是无法克服的。
| 归档时间: |
|
| 查看次数: |
117 次 |
| 最近记录: |