简体   繁体   English

如何防止从'0`构造std :: string引起的麻烦?

[英]How do I prevent trouble arising from std::string being constructed from `0`?

void foo (const std::string &s) {}

int main() {
  foo(0);   //compiles, but invariably causes runtime error
  return 0;
}

The compiler (g++ 4.4) apparently interprets 0 as char* NULL , and constructs s by calling string::string(const char*, const Allocator &a = Allocator()) . 编译器(g ++ 4.4)显然将0解释为char* NULL ,并通过调用string::string(const char*, const Allocator &a = Allocator())构造s Which is of course useless, because the NULL pointer is not a valid pointer to a c-string. 这当然没用,因为NULL指针不是指向c-string的有效指针。 This misinterpretation does not arise when I try to call foo(1) , this helpfully produces a compile-time error. 当我尝试调用foo(1) ,这种误解不会出现,这有助于产生编译时错误。

Is there any possibility to get such an error or warning at compile-time when I accidentally call a function like 当我不小心调用类似的函数时,是否有可能在编译时得到这样的错误或警告

void bar(const std::string &s, int i=1);

with bar(0) , forgetting about the string , and actually meaning to have i=0 ? bar(0) ,忘记string ,实际上意味着i=0

This is kind of ugly, but you could create a template that will produce an error when instantiated: 这有点难看,但你可以创建一个在实例化时会产生错误的模板:

template <typename T>
void bar(T const&)
{
    T::youHaveCalledBarWithSomethingThatIsntAStringYouIdiot();
}

void bar(std::string const& s, int i = 1)
{
    // Normal implementation
}

void bar(char const* s, int i = 1)
{
    bar(std::string(s), i);
}

Then using it: 然后使用它:

bar(0); // produces compile time error
bar("Hello, world!"); // fine

One somewhat clean workaround... 一个有点干净的解决方法......

#include <cassert>

void foo (const std::string &s)
{
    // Your function
}

void foo(const char *s)
{
     assert(s != 0);
     foo(std::string(s));
}

Actually static asserts would work too. 实际上静态断言也会起作用。 consider this: 考虑一下:

void foo (const std::string &s)
{
    // Your function
}

void foo(const char *s)
{
    #ifdef CPP_OH_X
    static_assert(s == 0, "Cannot pass 0 as an argument to foo!");
    #else
    typedef int[(s != 0) ? 1 : -1] check;
    #endif
    foo(std::string(s));
}

The idea here is to use static_assert which is a upcoming feature in C++ and is already implemented in various compilers; 这里的想法是使用static_assert,它是C ++即将推出的功能,已经在各种编译器中实现; primarly the ones that support C++0x. 主要是支持C ++ 0x的那些。 Now if you're not using C++0x you can use the alternitive method, which basicly typedefs an integer with a negitive value on failure. 现在,如果您不使用C ++ 0x,则可以使用交替方法,该方法基本上键入一个在失败时具有负值的整数。 Something which is not allowed and will produce an error at compile time 一些不允许的东西,会在编译时产生错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM