Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ "virtual" keyword placement

When I was writing an interface today in Visual Studio 2015 I noticed some weird behaviour. The placement of the "virtual" keyword before a function identifier normally doesn't matter, but if its placed after a pointer or reference, it complains. See the following:

class B {};

class A
{
    virtual B fun1a(); // OK
    B virtual fun1b(); // OK

    virtual B& fun2a(); // OK
    B& virtual fun2b(); // ERROR, "expected an identifier"

    virtual B* fun3a(); // OK
    B* virtual fun3b(); // ERROR, "expected an identifier"

    virtual std::unique_ptr<B> fun4a(); // OK
    std::unique_ptr<B> virtual fun4b(); // OK
};

Why is this?

And obviously I can avoid the errors completely by always putting the virtual keyword first, but I would've liked to be able to write function definitions the following way:

foo const & // return value and relevant keywords on one line
virtual bar( const baz &a ) const // function identifier, arguments, and relevant keywords on another line
{
    /* method implementation */
}

Alas, this is not possible for functions returning a reference or pointer...

Is this syntax error language-specific or Visual Studio localized?

like image 922
Falkgaard Avatar asked Oct 17 '22 13:10

Falkgaard


2 Answers

Have you considered using trailing return types? They would allow you to achieve your goal of putting the return type on its own line:

#include <memory>

class B {};

class A
{
    virtual auto fun1a()
    -> B;

    virtual auto fun1a() const
    -> B;

    virtual auto fun2a()
    -> B&;

    virtual auto fun2a() const
    -> B&;

    virtual auto fun2ac()
    -> B const&;

    virtual auto fun2ac() const
    -> B const&;

    virtual auto fun3b()
    -> B*;

    virtual auto fun3b() const
    -> B*;

    virtual auto fun3bc()
    -> B const*;

    virtual auto fun3bc() const
    -> B const*;

    virtual auto fun4a()
    -> std::unique_ptr<B>;

    virtual auto fun4a() const
    -> std::unique_ptr<B>;
};

The caveat is that if you use final or override, then you have put them after the return type:

virtual auto fun3bc() const
-> B const*
final;

Keep that in mind, though, that such a coding convention (putting final or override on its own line) is highly unusual. Just because C++ allows you to use it, it isn't necessarily a good idea.

like image 120
Christian Hackl Avatar answered Oct 20 '22 23:10

Christian Hackl


Try this

baz const // return value and relevant keywords on one line
virtual &foo::bar( arg a, arg b ) const // function identifier, arguments, and relevant keywords on another line
{
    /* method implementation */
}
like image 35
Ivan Salo Avatar answered Oct 20 '22 23:10

Ivan Salo