Using the indirect parent method

Consider the following code:

class user_error : public std::runtime_error
{
public:
    using std::exception::what;
    explicit user_error(const std::string& what_arg):std::runtime_error(what_arg){}
};


class with_overriden_what : public user_error {
public:
  with_overriden_what(const std::string& val) : user_error("user_error"), message(val) { }

  std::string message;

  virtual const char* what() const noexcept {
    return message.c_str();
  }
};

with these calls:

with_overriden_what ex("thrown");
std::cout << "1. direct result: " << ex.what() << "\n";
std::cout << "2. sliced result: " << static_cast<user_error>(ex).what() << "\n";
std::cout << "3. ranged result: " << ex.user_error::what() << "\n";

It is unexpected for me that the result of 2 and 3 is different:

1. direct result: thrown
2. sliced result: user_error
3. ranged result: std::exception

Q: Is there a paragraph in the standard that takes this behavior into account?

+6
source share
1 answer

2. 3. , 2. (== ) (== call). , (. ). 2. , std::runtime_error::what, "user_error", , :

[runtime.error]

runtime_error(const char* what_arg);

4  : runtime_error.

5   : strcmp(what(), what_arg) == 0.


, .

[class.virtual]

15 scope (5.1) .

3. . using , , .

, user_error::what std::runtime_error::what. user_error::what std::exception::what.


, , std::exception::what ? ( ):

[]

7 : NTBS, . ( )

, - , , , , . .


, :

#include <iostream>

struct A {
    virtual void x() {
        std::cout << "A\n";
    }
};

struct B : A {
    void x() {
        std::cout << "B\n";
    }
};

struct C : B {
    using A::x;
};

int main() {
    C c;
    c.x();
    c.C::x();
    return 0;
}

.

+4

All Articles