производные классы & amp; проверка типа

Я пытаюсь написать метод, который принимает класс, полученный из 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 или применить более строгую проверку типов компилятором, чтобы заставить это работать так, как мне бы хотелось?

0

Решение

Проблема ваша NotAString(std::string str) конструктор не explicit так что это позволяет неявные преобразования из std::string в NotAString,

Когда вы вызываете функцию с std::string компилятор замечает, что вы можете вызвать его путем преобразования аргумента через конструктор, поэтому он создает NotAString временно и передает его в функцию.

Если вы объявите это explicit NotAString(std::string str) тогда это не позволит эти неявные преобразования.

Ваши попытки проверить тип внутри функция никогда не будет работать, к этому моменту компилятор должен создать NotAString и все, что вы тестируете, является ли NotAString аргумент не является NotAString … который, очевидно, не будет работать.

2

Другие решения

Оставьте в стороне плохие дизайнерские идеи, замените этот конструктор …

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 когда они используются в качестве параметра функции.

0

По вопросам рекламы [email protected]