0

std::string から派生したクラスを引数として取るメソッドを作成しようとしています。このメソッドは、いくつかの異なる関数シグネチャでオーバーロードされています。std::string、または少なくとも実行時エラーで呼び出そうとすると、コンパイルが失敗することを望みますが、どうやらコンパイラは私には賢すぎるようです。

class NotAString : public std::string {
    NotAString(std::string str) : std::string(str) { }
};


class Foo {
   Foo();
   void bar(NotAString);
   void bar(int)
};

これはコンパイルして実行します

Foo foo();
foo.bar(NotAString("baz"));

しかし、これもそうです:

Foo foo();
foo.bar(std::string("baz"));

次のように typeid(str) を使用してみました:

void Foo::Bar(NotAString str) {
    if(typeid(&str) != typeid(new NotAString()) {
        throw std::bad_typeid();
    }
}

ただし、std::string または NotAString を渡すと、常に例外がスローされます。次のように dynamic_cast を使用してみました。

void Foo::Bar(NotAString str) {
    if (dynamic_cast<NotAString*>(&str) == NULL) {
        throw std::bad_type();
    }
}

しかし、例外をスローすることはありません。

目標は、文字列とキー値ルックアップのキーを表す文字列を区別できるようにすることです。NotAString クラスを変更したり、コンパイラによるより厳密な型チェックを適用して、これを希望どおりに動作させるにはどうすればよいですか?

4

2 に答える 2

2

問題は、NotAString(std::string str)コンストラクターがそうではないため、 からへexplicitの暗黙的な変換を許可することです。std::stringNotAString

で関数を呼び出すstd::stringと、コンストラクターを介して引数を変換することで呼び出すことができることにコンパイラーが気付くため、NotAString一時的なを作成して関数に渡します。

それを宣言するとexplicit NotAString(std::string str)、それらの暗黙的な変換は許可されません。

関数内の型をチェックしようとする試みは決してうまくいきません。その時点までに、コンパイラは aNotAStringを作成し、テストしているのはNotAString引数が a ではないかどうかだけですNotAString... これは明らかに機能しません。

于 2013-01-28T19:30:28.900 に答える
0

悪い設計アイデアはさておき、このコンストラクタを変更してください...

class NotAString : public std::string {
    NotAString(std::string str) : std::string(str) { }
};

...になるexplicit

class NotAString : public std::string {
    explicit NotAString(std::string str) : std::string(str) { }
};

これにより、オブジェクトが関数パラメーターとして使用されるときにstd::stringオブジェクトが暗黙的に変換されるのを防ぐことができます。NotAString

于 2013-01-28T19:31:42.700 に答える