3

You'll find the following text in [basic.def.odr]/2 in C++11:

A virtual member function is odr-used if it is not pure. A non-overloaded function whose name appears as a potentially-evaluated expression or a member of a set of candidate functions, if selected by overload resolution when referred to from a potentially-evaluated expression, is odr-used, unless it is a pure virtual function and its name is not explicitly qualified.

According to highlighted text above, it's possible to invoke a pure virtual function as a potentially-evaluated expression, without its name being explicitly qualified. This answer by Michael Burr seems to show the only way, one can call a pure virtual function, and it has to use a qualified name.

PS: For those wondering why am I still referring the question to the C++11 Standard, please see my prior question here.

Community
  • 1
  • 1
João Afonso
  • 1,934
  • 13
  • 19
  • As a guess, `struct Foo { virtual void bar() = 0; }; Foo* f = blah; f->bar();`; `bar` is a named pure virtual function (selected for overload resolution) and its name is not explicitly qualified. Uncertain, so just a comment. – Yakk - Adam Nevraumont Mar 03 '17 at 21:26
  • 3
    What Yakk said. Note the difference between a function being selected by overload resolution and the function actually being called. (Though pure virtual functions can actually be called, during constructors or destructors; this is undefined behavior.) – aschepler Mar 03 '17 at 21:29
  • @aschepler, They can also be called normally, with qualification, like the answer linked by the OP shows. Your comment suggests to me that calling a pure virtual function requires a more obscure case. – chris Mar 03 '17 at 21:34

1 Answers1

3

How can a pure-virtual function be invoked without its name being explicitly qualified?

That's the ordinary case. To borrow Yakk's example from the comments:

struct Foo {
    virtual void bar() = 0;
};

void quux(Foo* f) {
    f->bar();
}

Here the pure virtual function Foo::bar is being invoked without explicit qualification. Therefore, according to the quoted paragraph, Foo::bar is not odr-used, and therefore it doesn't need to be defined. Instead, its non-pure overriders in derived classes are odr-used, and they are the functions that need to be defined.

But if you explicitly qualify a call to a pure virtual function, then you cause it to become odr-used, and it requires a definition. This most commonly happens with pure virtual destructors, because a derived class destructor always invokes base class destructors as though they were fully qualified. That's why pure virtual destructors need to be defined.

Barry
  • 286,269
  • 29
  • 621
  • 977
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • You example above doesn't make any sense to me. What is `blah`? – João Afonso Mar 03 '17 at 21:47
  • 1
    @JoãoAfonso Some expression of type `Foo*`. It doesn't matter what it is. – Brian Bi Mar 03 '17 at 21:58
  • 2
    @Brian `Here the pure virtual function Foo::bar is being invoked without explicit qualification.` This is wrong. `f->bar();` **doesn't invoke** the pure virtual function `Foo::bar()`, but some virtual function `D::bar()`, where `D` is a concrete class derived from `Foo`, and `f` is the address of some object of class `D`, materialized in the expression `blah`. – João Afonso Mar 04 '17 at 13:19
  • 1
    @JoãoAfonso If that bothers you, file an editorial issue against the standard. I explained to you what the paragraph means. If you don't believe me, I hope someone else writes an answer that you will believe. – Brian Bi Mar 04 '17 at 17:31
  • @Brian I'm accepting your answer, but I think [this post](https://groups.google.com/a/isocpp.org/d/msg/std-discussion/dgdLFuXpjkU/28s9kkgqAQAJ) by Nicol Bolas in C++ std-discussion provided me with [the insight](https://groups.google.com/a/isocpp.org/d/msg/std-discussion/dgdLFuXpjkU/xSA5-OJJAQAJ) that I was looking for in my question. – João Afonso Mar 05 '17 at 10:09