Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is mixing the old and new C++ function syntax in a class allowed?

Tags:

c++

c++14

auto

This code actually works:

class Abstract {
    virtual auto foo() -> int = 0;
};

class Concrete: public Abstract {
    int foo() { cout << "blah!" << endl; return 1; }
} instance;

I understand that the function gets mangled and linked to be the same function signature, but is this kind of mixing actually legal in C++14?

like image 203
Philipp Avatar asked Jul 28 '16 15:07

Philipp


People also ask

Does the old syntax for function definition still work?

While the old syntax for function definition still works (with warnings, if you ask your compiler), using them does not provide function prototypes. Without function prototypes the compiler will not check if the functions are called correctly.

Can I mix C and C++ programming languages?

BTW there is another way to handle this whole thing: compile all your code (even your C-style code) using a C++ compiler. That pretty much eliminates the need to mix C and C++, plus it will cause you to be more careful (and possibly-hopefully!- discover some bugs) in your C-style code.

What are old style functions in C?

Old-style function declarations also generate warnings if you subsequently declare or define the same function with either an ellipsis or a parameter with a type that is not the same as its promoted type. The next section, C Function Definitions, shows the syntax for function definitions, including the old-style syntax.

Is k&r syntax still used in C?

That's the old-style syntax for parameter lists, which is still supported. In K&R C you could also leave off the type declarations and they would default to int. i.e. would be the same function. Both C89/90 and C99 still officially support K&R style declarations.


2 Answers

auto foo()->int and int foo() are the same prototype expressed with different syntax, so the second function is an override of the first, and will replace it in runtime dispatch (being virtual) as usually.

The right-side return syntax, has normally another purpose, like

template<class A, class B>
auto some_combination(A a, B b) -> decltype(a+b);

otherwise requiring a more complex syntax like

temlate<class A, class B>
decltype(std::declval<A>()+std::declval<B>()) some_combination(A a,B b);

since a and b are not defined in the left side of the prototype.

When the return type is trivially defined, left or right placement is essentially irrelevant.

like image 96
Emilio Garavaglia Avatar answered Nov 10 '22 09:11

Emilio Garavaglia


It's legal because actually you are fully defining your function.
As a minimal, working example (note the override):

class Abstract {
    virtual auto foo() -> int = 0;
};

class Concrete: public Abstract {
    int foo() override { return 1; }
} instance;

int main() { }

Here the return type isn't deduced, it's explicitly declared by means of a trailing return type.
It's equivalent to:

class Abstract {
    virtual int foo() = 0;
};

It would have been different if you were using this:

class Abstract {
    virtual auto foo() = 0;
};

Here template deduction is involved and virtual functions cannot have deduced return type (that is more or less the error string from GCC).

like image 25
skypjack Avatar answered Nov 10 '22 09:11

skypjack