这工作
与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