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

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

コンパイラ (g++ 4.4) は明らかに として解釈0し、 を呼び出しchar* NULLて構築します。ポインターは c-string への有効なポインターではないため、これはもちろん役に立ちません。を呼び出そうとしても、この誤解は発生しません。これにより、コンパイル時にエラーが発生します。sstring::string(const char*, const Allocator &a = Allocator())NULLfoo(1)

次のような関数を誤って呼び出したときに、コンパイル時にそのようなエラーまたは警告が発生する可能性はありますか?

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

bar(0)、 を忘れて、string実際に持つ意味は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

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

ここでのアイデアは、C++ の今後の機能であり、さまざまなコンパイラで既に実装されている static_assert を使用することです。主に C++0x をサポートするもの。C++0x を使用していない場合は、別の方法を使用できます。これは基本的に、失敗時に負の値を持つ整数を型定義します。許可されておらず、コンパイル時にエラーが発生するもの

于 2011-06-27T04:15:55.187 に答える