我正在尝试编写一种方法,该方法采用从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::stringNotAString的隐式转换。

当使用std::string调用函数时,编译器会注意到您可以通过构造函数转换参数来调用它,因此它会创建一个NotAString临时变量并将其传递给函数。

如果将其声明为explicit NotAString(std::string str),则它将不允许这些隐式转换。

您尝试检查函数内部类型的尝试永远不会成功,到那时编译器已经创建了一个NotAString,而您正在测试的是NotAString参数是否不是NotAString ...显然是行不通的。

关于c++ - 派生类和类型检查,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14569642/

10-09 17:28