Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ concat中的变量模板和推断返回类型 这很有效_C++_C++11_G++_Type Inference_Variadic Templates - Fatal编程技术网

C++ concat中的变量模板和推断返回类型 这很有效

C++ concat中的变量模板和推断返回类型 这很有效,c++,c++11,g++,type-inference,variadic-templates,C++,C++11,G++,Type Inference,Variadic Templates,玩弄C++11,我试图通过将任意对象写入ostringstream来构建一个连接任意对象的函数。作为这些工具的帮助函数,我有一个可变的帮助函数,它将单个项目附加到下面完整粘贴中给出的现有ostream More上下文中: template<class Head, class... Tail> std::ostream& append(std::ostream& out, const Head& head, const Tail&... tail) {

玩弄C++11,我试图通过将任意对象写入ostringstream来构建一个连接任意对象的函数。作为这些工具的帮助函数,我有一个可变的帮助函数,它将单个项目附加到下面完整粘贴中给出的现有ostream More上下文中:

template<class Head, class... Tail>
std::ostream& append(std::ostream& out, const Head& head, const Tail&... tail)
{
  return append(out << head, tail...);
}
问题 所以我的核心问题是: 这段代码失败的原因是否充分

我感兴趣的要么是引用标准中说我的代码无效的部分,要么是对实现中出现的问题的一些见解。如果有人为此发现了一个gcc错误,这也是一个答案。我还没有找到合适的报告。尽管使用std::ostream仅对我当前的应用程序有效,但实现这一点的方法也很好。关于其他编译器如何处理这一点的输入也很受欢迎,但对于我将接受的答案来说,这是不够的。 3.3.2[基本范围pdecl] -1-名称的声明点紧跟在其完整声明人第8条之后,以及其初始值设定人(如有)之前,除非下文另有说明

函数声明符包含尾部返回类型,因此函数本身的名称不在其尾部返回类型的范围内

所以在表达式decltypeappendout中 3.3.2[基本范围pdecl] -1-名称的声明点紧跟在其完整声明人第8条之后,以及其初始值设定人(如有)之前,除非下文另有说明

函数声明符包含尾部返回类型,因此函数本身的名称不在其尾部返回类型的范围内


因此,在表达式decltypeappendout中,我发现添加带有行号的代码和带有行号的错误很有趣,但这些行号不匹配。您确定错误在尾部返回类型中吗?您可以通过将append return设置为void来测试这一点,因为您根本不使用返回类型,所以不需要返回任何内容。注意,我看不出该代码在语法层面上有任何明显的错误,我相信它应该编译。你测试过其他编译器吗?@DavidRodríguez dribeas:是的,它是尾随返回类型。根据Jonathan Wakely的回答,这甚至是有道理的。使用void返回类型确实会使问题消失,正如您所指出的,这似乎是一个完美的解决方法。所以我想请你们也提出这一点作为回答,这样我也可以给你们投票。这些答案可以很好地相互补充,一个给出原因,另一个给出解决方法。我发现有趣的是,您添加了带有行号的代码,以及带有行号的错误,但这些行号不匹配。您确定错误在尾部返回类型中吗?您可以通过将append return设置为void来测试这一点,因为您根本不使用返回类型,所以不需要返回任何内容。注意,我看不出该代码在语法层面上有任何明显的错误,我相信它应该编译。你测试过其他编译器吗?@DavidRodríguez dribeas:是的,它是尾随返回类型。根据Jonathan Wakely的回答,这甚至是有道理的。使用void返回类型确实会使问题消失,正如您所指出的,这似乎是一个完美的解决方法。所以我想请你们也提出这一点作为回答,这样我也可以给你们投票。这些答案将很好地相互补充,一个给出原因,另一个给出解决方法。无论是在内容上还是在表达上,答案都很棒。谢谢在这种特殊情况下,另一个解决方法是使ADL能够在实例化时找到它。我想这种类型的s可能会被滥用。类似于struct MyADLFinder:std::ostringstream{};考虑到函数的使用,第三个更简单的解决方法是根本不返回任何内容,并且具有一个void返回类型。@DavidRodríguez dribeas,是的,这更有意义!无论是在内容上还是在表达上,答案都很好。谢谢在这种特殊情况下,另一个解决方法是使ADL能够在实例化时找到它。我想这种类型的s可能会被滥用。类似于struct MyADLFinder:std::ostringstream{};考虑到函数的使用,第三个更简单的解决方法是根本不返回任何内容,并且具有一个void返回类型。@DavidRodríguez dribeas,是的,这更有意义!
  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 }
 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
template<class Stream, class Head, class... Tail>
  auto append(Stream& out, const Head& head, const Tail&... tail)
  -> typename std::common_type<decltype(out << head), decltype(out << tail)...>::type