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

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

编译器(g++ 4.4)显然解释0char* NULL,并s通过调用string::string(const char*, const Allocator &a = Allocator()). 这当然没用,因为NULL指针不是指向 c 字符串的有效指针。当我尝试调用时不会出现这种误解foo(1),这有助于产生编译时错误。

当我不小心调用类似的函数时,是否有可能在编译时出现这样的错误或警告

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

with bar(0), 忘记 the string, 真正的意思 to have i=0?

4

3 回答 3

10

这有点难看,但是您可以创建一个在实例化时会产生错误的模板:

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

然后使用它:

bar(0); // produces compile time error
bar("Hello, world!"); // fine
于 2011-06-26T14:10:51.610 回答
1

一种有点干净的解决方法......

#include <cassert>

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

void foo(const char *s)
{
     assert(s != 0);
     foo(std::string(s));
}
于 2011-06-26T14:17:35.677 回答
-2

实际上静态断言也可以。考虑一下:

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

这里的想法是使用 static_assert,这是 C++ 中即将推出的功能,并且已经在各种编译器中实现;主要是那些支持 C++0x 的。现在,如果您不使用 C++0x,则可以使用替代方法,该方法基本上会在失败时将整数类型定义为负值。不允许的并且会在编译时产生错误的东西

于 2011-06-27T04:15:55.187 回答