我正在尝试编写一种方法,该方法采用从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类或通过编译器强制进行更严格的类型检查,以使其按我的意愿工作?
最佳答案
问题是您的NotAString(std::string str)
构造函数不是explicit
,因此它允许从std::string
到NotAString
的隐式转换。
当使用std::string
调用函数时,编译器会注意到您可以通过构造函数转换参数来调用它,因此它会创建一个NotAString
临时变量并将其传递给函数。
如果将其声明为explicit NotAString(std::string str)
,则它将不允许这些隐式转换。
您尝试检查函数内部类型的尝试永远不会成功,到那时编译器已经创建了一个NotAString
,而您正在测试的是NotAString
参数是否不是NotAString
...显然是行不通的。
关于c++ - 派生类和类型检查,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14569642/