Reputation: 31
I was trying out codefights.com and noticed someones answer to a question which involved giving all the longest strings in a vector do this:
std::vector<std::string> r, allLongestStrings(std::vector<std::string> a) {
int b=0;
for (s:a) if (s.size()>b) b=s.size();
for (s:a) if (s.size()==b) r.push_back(s);
return r;
}
He's declaring a variable in the return type specifier for the function, can anyone tell me why this is allowed? I't doesn't compile on my machine and I couldn't find a gcc extension that does this, thanks in advance :).
Upvotes: 2
Views: 828
Reputation: 37599
The mixed variable / function declaration seems to be ok, though gcc complains that function definition shouldn't be there but I think it's ok at global scope. But it's a 100% valid syntax even in non-global scope if no function definition is given. This declaration is just regular declarations of several items of the same leading type. For example we can declare multiple items of different kinds but with same leading like this:
// single line declaration
int i = 0, * p_i = nullptr, ai[2] = {42,42}, geti(void), * * getppi(void);
// the same as
int i = 0;
int * p_i = nullptr;
int ai[2] = {42, 42};
int geti(void);
int ** getppi(void);
So r
is just a regular variable of type std::vector<std::string>
, followed by function allLongestStrings that returns the same std::vector type.
This compact declaration form exists for historical reasons. Basically it helped to save quite some bytes for storing and compiling the source file.
This form of for
loop is probably on of the earlier experimental extensions before current form was standardized.
Upvotes: 0
Reputation: 27776
Looking at the reference (decl-specifier-seq), I don't see how it would be possible to declare the return variable before the function name.
With C++14, you can use the auto
keyword to remove the duplicate mentioning of the return type:
auto allLongestStrings( const std::vector<std::string>& a ) {
std::vector<std::string> r;
std::size_t b = 0;
for( const auto& s : a ) if( s.size() > b ) b = s.size();
for( const auto& s : a ) if( s.size() == b ) r.push_back( s );
return r;
}
I fixed some other things of the code:
a
as const reference, so it won't be copiedb
as std::size_t
to match return type of std::vector::size()
auto
); added const reference for efficiencyUpvotes: 1