Difference or benefit of auto myFunc() -> int and int myFunc() [duplicate] - c++

This question already has answers here:
Should the trailing return type syntax style become the default for new C++11 programs? [closed]
(4 answers)
Closed 8 years ago.
Having looked at a few online documents on C++14, I found the following syntax for defining a function in C++14 that uses trailing return types:
auto myFunc() -> int {}
my question is, other then using this way for using decltype in the argument and some other scenarios, is there a difference or any benefit for using the above syntax for bog standard functions like:
int myFunc() {}

Argument for : coherence.
This way you don't have the freak function needing a trailing return type standing out.
Argument against : wow that's ugly.[pers. opinion]
Semantic difference : none.

Related

Trailing return type in non-template functions [duplicate]

This question already has answers here:
Should the trailing return type syntax style become the default for new C++11 programs? [closed]
(4 answers)
Closed 2 years ago.
I have seen people using the following syntax to implement functions:
auto get_next() -> int
{
/// ...
}
Instead of:
int get_next()
{
/// ...
}
I understand both and I know that the trailing return type syntax is useful for template code using decltype. Personally I would avoid that syntax for other code since when reading code I prefer to read the concrete return type of a function first, not last.
Is there any advantage in using the trailing return type syntax for non-template code as shown above (except personal preference or style)?
In addition to sergeyrar's answer, those are the points I could imagine someone might like about trailing return types for non-template functions:
Specifying a return type for lambda expressions and functions is identical w.r.t. the syntax.
When you read a function signature left-to-right, the function parameters come first. This might make more sense, as any function will need the parameters to produce any outcome in the form of a return value.
You can use function parameter types when specifying the return type (the inverse doesn't work):
auto f(int x) -> decltype(x)
{
return x + 42;
}
That doesn't make sense in the example above, but think about long iterator type names.
One potential benefit is that it makes all of your declared function names line up:
auto get_next(int x, int y) -> int;
auto divide(double x, double y) -> double;
auto printSomething() -> void;
auto generateSubstring(const std::string &s, int start, int len) -> std::string;
source: https://www.learncpp.com/cpp-tutorial/the-auto-keyword/
Well you already mentioned the major use case of the trailing return type. It's usage if the return type depends on the arguments.
If we exclude that use case the only advantage you might gain is an enhanced readability of your code, especially if your return type is a bit more complex, but you don't have a technical benefit of using the trailing return in that scenario.

Why doesn't C++ allow implicit list initialization in the conditional operator? [duplicate]

This question already has answers here:
Why can I use initializer lists on the right-hand side of operator += but not operator+?
(3 answers)
Closed 3 years ago.
This code compiles:
std::string f(bool a, std::string const& b)
{
if (a) return b;
return {};
}
This code also compiles:
std::string f(bool a, std::string const& b)
{
return a ? b : std::string{};
}
This code does not compile:
std::string f(bool a, std::string const& b)
{
return a ? b : {};
}
Given that both result values of the ?: operator are required to be the same type, why doesn't it infer the type like it does in the first example?
It appears that this question might have a similar answer to this (which essentially boils down to "because nobody thought about it when writing the language specification"). However I still think it's useful to retain this question as the question itself is different, it's still sufficiently surprising, and the other wouldn't come up in searches for this issue.
A braced initializer is not an expression and thus it has no type. See:
https://scottmeyers.blogspot.com/2014/03/if-braced-initializers-have-no-type-why.html
A braced initializer is a grammatical construct with special rules in the standard, explicitly specifying allowed use and type deduction. These special rules are needed exactly because braced initializers have no type. Using them in ?: statements is not specified, and thus the program is ill-formed.
If you really need to hear the man himself say it three times in a row before you believe it, then:
https://youtu.be/wQxj20X-tIU?t=1792

What is the type of a "variable" containing a lambda function that captures by reference? [duplicate]

This question already has answers here:
What is the type of lambda when deduced with "auto" in C++11?
(8 answers)
Closed 5 years ago.
I was doing a quick experiment with lambda functions and I'm having trouble figuring out how to declare the testFunc variable below.
Generally speaking, a function pointer can be defined as follows:
int (*someFunc)(int, int) = otherFunction;
When doing this for a lambda function without any closures, it works fine:
int (*someFunc)(int) = [](int a) -> int { return 0; };
However, I get a compiler error when trying to capture by reference:
void (*testFunc)() = [&]() -> void { /* code here */ };
It works if I declare testfunc as auto instead, but I'm curious what's wrong with the above code?
It's pretty simple:
All lambdas have unique anonymous types. (that's why auto works)
Lambdas without captures are convertible to function pointers, but capturing lambdas are not.

what's `auto classMemberFunction()->void {}` signature? [duplicate]

This question already has answers here:
Should the trailing return type syntax style become the default for new C++11 programs? [closed]
(4 answers)
Closed 6 years ago.
I've seen in an article a code similar to this one:
#include <iostream>
class MyClass {
public:
auto myFunction(int i)->void {
std::cout << "Argument is " << i << std::endl;
}
};
void main() {
MyClass myClass;
myClass.myFunction(4);
}
The program prints correctly the output Argument is 4, but I don't understand the signature of the class function member and what's its difference with the usual one. When it's useful to use this different signature rather than void myFunction(int i)?
This is an (ab)use of the trailing-return-type syntax that has been introduced in C++11. The syntax is:
auto functionName(params) -> returnType;
auto functionName(params) -> returnType { }
It works the same as a classic function declaration with the return type on the left, except that the trailing type can use names introduced by the function's signature, i.e:
T Class::function(param); // No particular behaviour
auto Class::function(param) -> T; // T can use Class::Foo as Foo, decltype(param), etc.
In this case though, there is no point except consistency.

Why in-class initializer can't use ( ) [duplicate]

This question already has answers here:
Why can't member initializers use parentheses?
(2 answers)
Closed 6 years ago.
Today when I read C++ Primer ,it said in-class initializer can't use () I have searched on Stackoverflow and find a similar question here.And the accepted answer say:the reason might be that there is a ambiguous between declaration of a member function and definition of a member of type.But I am not complete agree with him.I try the following code:
struct Sales_data
{
int i(5); //this line can't be regard as a function
};
But the compiler still complain.Who can tell me why.\
compiler:clang++ version:3-4
It is disallowed by the language. The reason is that there would be cases where it couldn't be disambiguated from a function declaration:
struct foo
{
int bar();
};
So instead of replicating the whole most vexing parse fiasco by allowing () to work sometimes, it is outright disallowed.