Я пробовал codefights.com и заметил, что кто-то ответил на вопрос, который включал в себя передачу всех самых длинных строк в векторе:
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;
}
Он объявляет переменную в спецификаторе возвращаемого типа для функции, может кто-нибудь сказать мне, почему это разрешено? Я не компилирую на своей машине, и я не смог найти расширение gcc, которое делает это, спасибо заранее :).
Глядя на ссылка (Децл-спецификатор-сл), Я не вижу, как можно было бы объявить возвращаемую переменную перед именем функции.
С C ++ 14 вы можете использовать auto
ключевое слово для удаления повторяющегося упоминания типа возвращаемого значения:
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;
}
Я исправил некоторые другие вещи кода:
a
как постоянная ссылка, поэтому он не будет скопированb
как std::size_t
соответствовать типу возвращаемого значения std::vector::size()
auto
); добавлена постоянная ссылка для эффективностиКажется, что смешанное объявление переменной / функции в порядке, хотя gcc жалуется, что определения функции там не должно быть, но я думаю, что это нормально в глобальной области видимости. Но это допустимый синтаксис на 100% даже в неглобальной области, если не дано определение функции. Это объявление является обычным объявлением нескольких элементов одного и того же начального типа. Например, мы можем объявить несколько элементов разных видов, но с одинаковыми ведущими, вот так:
// 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);
Так r
это просто обычная переменная типа std::vector<std::string>
Затем следует функция allLongestStrings, которая возвращает тот же тип std :: vector.
Эта компактная форма декларации существует по историческим причинам. В основном это помогло сохранить довольно много байтов для хранения и компиляции исходного файла.
Эта форма for
цикл, вероятно, входит в число более ранних экспериментальных расширений до того, как текущая форма была стандартизирована.