這工作
與C++ 11玩弄,我試圖建立其將其寫入一個ostringstream
串接任意對象的功能。至於那些輔助函數,我有追加一個項目,以現有的ostream
(下充分貼給我們更多的上下文中)一個可變參數的輔助功能:可變參數模板和推斷的返回類型的Concat
template<class Head, class... Tail>
std::ostream& append(std::ostream& out, const Head& head, const Tail&... tail)
{
return append(out << head, tail...);
}
這種失敗
但轉念一想當<<
應用於流時,可能會有一些對象不會返回ostream,而是返回某個佔位符。因此,這將是很酷的流類型模板參數,以及:
1 #include <iostream>
2 #include <sstream>
3
4 template<typename Stream>
5 Stream& append(Stream& out) {
6 return out;
7 }
8
9 template<class Stream, class Head, class... Tail>
10 auto append(Stream& out, const Head& head, const Tail&... tail)
11 -> decltype(append(out << head, tail...)) // <<<<< This is the important line!
12 {
13 return append(out << head, tail...);
14 }
15
16 template<class... Args>
17 std::string concat(const Args&... args) {
18 std::ostringstream s;
19 append(s, args...);
20 return s.str();
21 }
22
23 int main() {
24 std::cout << concat("foo ", 3, " bar ", 7) << std::endl;
25 }
但g++-4.7.1
會拒絕編譯這個。
更改的Stream
所有使用簽名回std::ostream
不會使任何更好,所以我假定new function declaration syntax正在發揮重要的作用在這裏 - 儘管GCC claims來支持它,因爲4.4。
錯誤消息
的錯誤信息是非常模糊的,並沒有告訴我這是怎麼回事。但也許你可以理解它。
In instantiation of ‘std::string concat(const Args& ...) [with Args = {char [5], int, char [6], int}; std::string = std::basic_string<char>]’:
24:44: required from here
19:3: error: no matching function for call to ‘append(std::ostringstream&, const char [5], const int&, const char [6], const int&)’
19:3: note: candidates are:
5:9: note: template<class Stream> Stream& append(Stream&)
5:9: note: template argument deduction/substitution failed:
19:3: note: candidate expects 1 argument, 5 provided
10:6: note: template<class Stream, class Head, class ... Tail> decltype (append((out << head), append::tail ...)) append(Stream&, const Head&, const Tail& ...)
10:6: note: template argument deduction/substitution failed:
In substitution of ‘template<class Stream, class Head, class ... Tail> decltype (append((out << head), tail ...)) append(Stream&, const Head&, const Tail& ...) [with Stream = std::basic_ostringstream<char>; Head = char [5]; Tail = {int, char [6], int}]’:
19:3: required from ‘std::string concat(const Args& ...) [with Args = {char [5], int, char [6], int}; std::string = std::basic_string<char>]’
24:44: required from here
10:6: error: no matching function for call to ‘append(std::basic_ostream<char>&, const int&, const char [6], const int&)’
10:6: note: candidate is:
5:9: note: template<class Stream> Stream& append(Stream&)
5:9: note: template argument deduction/substitution failed:
10:6: note: candidate expects 1 argument, 4 provided
問題
所以我的核心問題是:
是否有一個很好的理由代碼失敗?
我很想無論是從哪個說我的代碼是無效的標準,或者一些見解,以什麼錯在這裏執行一些報價。如果任何人都應該爲此找到一個gcc bug,那也是一個答案。我一直無法找到合適的報告。儘管使用std::ostream
只適用於我當前的應用程序,但使其工作的方式也很棒。關於其他編譯器如何處理這個問題的輸入也是值得讚賞的,但對於我認爲接受的答案來說還不夠。
我覺得有趣的是,你用行號加上了代碼,而行號錯誤,但這些號碼不匹配。你確定錯誤是在尾部返回類型嗎?你可以通過'append'返回'void'來測試它(你根本沒有使用返回類型,所以不需要返回任何東西)(注意,我沒有看到語法中的代碼有明顯的錯誤我相信它應該編譯,你測試過其他編譯器了嗎?) – 2012-07-22 01:30:12
@DavidRodríguez-dribeas:是的,它是最後一個返回類型,根據Jonathan Wakely的回答,這甚至是有道理的。 「返回類型確實會使問題消失,正如你所指出的那樣,這似乎是一個完美的解決方法,所以我也請你提出這個問題作爲答案,以便我可以給你一個補償,這些答案會很好地互補,一個給出理由,另一個解決方法。 – MvG 2012-07-22 09:21:51