2017-04-17 184 views
1

我嘗試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擴展,在此先感謝:)。

+3

您確定該解決方案有效嗎?正如所寫,這似乎不是有效的C++。 – merlin2011

+1

以任何方式無效的C++。 GCC的某些版本允許使用這種範圍內的形式,但後來由於標準禁止它而被刪除。至於在返回類型中聲明變量...什麼? – DeiDei

+0

我知道,for循環也困惑我,但它在codefights網站上工作,並通過所有測試:S –

回答

1

看看referencedecl-specifier-seq),我不明白如何在函數名稱前面聲明返回變量。

用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爲常量參考,因此它不會被複制
  • 聲明bstd::size_t以匹配返回類型std::vector::size()
  • 在range-for循環中,需要類型說明符(即使它是auto);爲了提高效率

Live demo.

+0

我認爲,那是一個逗號運算符,它是測試單元代碼的一個漏洞<。 – Swift

0

混合變量/函數聲明添加const引用似乎是確定,但海灣合作委員會抱怨說,函數定義不應該存在,但我認爲這是在全局範圍內確定。但是,如果沒有給出函數定義,即使在非全局範圍內,它也是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); 

所以rstd::vector<std::string>類型的只是一個普通的變量,然後返回相同的std ::矢量型功能allLongestStrings。

由於歷史原因,這種簡潔的聲明形式存在。基本上它有助於節省一些字節來存儲和編譯源文件。

此形式的for循環可能是在當前表單標準化之前的較早實驗擴展。

+0

您的示例顯示了混合變量聲明和函數聲明。OP的代碼是將變量聲明和函數定義混合在一起,這不是一回事,也是不允許的。 – interjay

+0

不,它在全球範圍內是不好的..我試圖找出他們使用什麼包裝,但失敗,在所有現代編譯器將通過任何嘗試通過逗號結合變量聲明和函數定義的錯誤...無論他們有非常過時的或異乎尋常的編譯器,並且它們的封裝器是某種模板,其中的答案被粘貼或者發生了一些真正奇怪的事情 – Swift

+0

[IntelCC似乎允許](https://godbolt.org/g/7JERJT)將函數定義在OP的例子中,變量之後的全局範圍。 – VTT