Skip to content

[BUG] Unable to override a non-ref-qualified virtual function declared in a Cpp1 library #694

Closed
@fedapo

Description

@fedapo

Describe the bug
Not sure whether this applies as a bug, but it is a design decision that affects the way Cpp2 interacts with existing libraries and might get in the way of a gradual migration from a Cpp1 codebase to Cpp2.
The scenario is a Cpp2 type (e.g. new migrated code) that inherits from a Cpp1 class/struct (e.g. legacy/library code) with virtual functions declared with no ref-qualifier.

To Reproduce
This is the code in the Cpp1 header file.

struct BaseClass {
    virtual ~BaseClass() = default;

    virtual std::string get_info() const {
        return "base";
    }
};

Then a Cpp2 type is defined.

DerivedClass: type = {
    this: BaseClass = ();

    get_info: (override this) -> std::string = {
        return "derived";
    }
}

Compiling this example gives this error:

/.../override_problem.cpp2:6:32: error: cannot overload a member function with ref-qualifier '&' with a member function without a ref-qualifier
    public: [[nodiscard]] auto get_info() const& -> std::string override;

The reason is clear: Cpp2 emits member functions that have either an lvalue ref-qualifier (const &, when declared with in this; &, when declared with inout this) or an rvalue ref-qualifier (&&, when declared with move this), yet the base class virtual function is declared with no qualifier hence the override is illegal and impossible. AFAIK no mechanism is available to declare the member function with no ref-qualifier to match the base class virtual function declaration and avoid the error.

Additional context
The choice of always using an explicit ref-qualifier for member function is rather recent, the code where I noticed the issue was working fine until a few weeks ago. I'm not sure whether I'm missing something major here and this is a non-problem; perhaps I'm just ignorant of another way to arrange this.
If the problem is real I see a few scenarios to treat it.

  1. Ignore it. Inheriting from a base class of a C++ library that has virtual functions declared with no ref-qualifier just won't be possible. The case is rather common, though. It came out while trying to use a popular C++ testing library in Cpp2. Other examples abound, just think of any C++ GUI library, such as wxWidgets, or C++ frameworks, such as Poco.
  2. Use another keyword from the ones available to "decorate" this in the member function declaration to avoid the ref-qualifier. I see some problem with the semantics in this case. For instance, say copy this is used, the meaning in common English of the keyword copy would be of no help and forward this is probably even worse. In this respect the choice of C/C++ to stay away from keywords when possible and use operators, such as '&', devoid of any baggage in meaning, posed less problems.
  3. Introduce a new keyword. Most probably not a viable solution for design economy reasons.

That's it. Please, forgive me for having taken such a large text to describe it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions