不能将typeof(std :: endl)作为模板参数?

Max*_*Max 10 c++ variadic-templates c++11

所以,我试图写一个这样的函数:

void append_to_stream(std::ostream &stream)
{ }

template <typename T, typename... Args>
void append_to_stream(std::ostream &stream, T first, Args&&... rest)
{
  stream << first;
  append_to_stream(stream, rest...);
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

append_to_stream(stream, 
                 std::endl,
                 std::endl);
Run Code Online (Sandbox Code Playgroud)

但这不起作用.我收到一个错误,指出该函数的"参数太多".我把它缩小到我知道这std::endl是有罪的地步- 可能是因为它是一个功能.我设法通过声明一个被调用的结构来"解决"这个问题endl并定义<<operator它以便它只是调用它std::endl.这有效,但感觉不是特别好.是不是可以接受std :: endl作为模板参数?该功能适用​​于其他类型.

编辑:这是错误:

src/log/sinks/file_sink.cpp:62:21: error: too many arguments to function ‘void log::sinks::append_to_stream(std::string&, Args&& ...) [with Args = {}, std::string = std::basic_string<char>]’
Run Code Online (Sandbox Code Playgroud)

更新

试图让编译器推导出正确的模板参数@MooingDuck建议可以使用以下形式的函数:

  template<class e, class t, class a> 
  basic_ostream<e,t>&(*)(basic_ostream<e,t>&os) get_endl(basic_string<e,t,a>& s) 
  {
return std::endl<e,t>;
  }
Run Code Online (Sandbox Code Playgroud)

但是,这不编译.

错误:

src/log/sinks/file_sink.cpp:42:28: error: expected unqualified-id before ‘)’ token
src/log/sinks/file_sink.cpp:42:53: error: expected initializer before ‘get_endl’
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?为了编译这个,我补充道using namespace std;

Rob*_*obᵩ 15

std::endl是一个模板,而不是一个函数,编译器无法解析endl使用哪个.

尝试:

append_to_stream(std::cout,
             std::endl<char, std::char_traits<char>>,
             std::endl<char, std::char_traits<char>>);
Run Code Online (Sandbox Code Playgroud)

或者,MooingDuck的解决方案(更正):

template<class e, class t, class a> //string version
std::basic_ostream<e, t>& (*get_endl(const std::basic_string<e, t, a>&))
    (std::basic_ostream<e, t>& )
{ return std::endl<e,t>; } 

template<class e, class t> //stream version
std::basic_ostream<e, t>& (*get_endl(const std::basic_ostream<e, t>&))
    (std::basic_ostream<e, t>& )
{ return std::endl<e,t>; }

int main () {
  std::ostream& stream = std::cout;
  append_to_stream(stream,
                 get_endl(stream),
                 get_endl(stream));
}
Run Code Online (Sandbox Code Playgroud)

这是get_endl解决方案,由C++ 11 decltype特性简化:

template<class e, class t, class a> //string version
auto get_endl(const std::basic_string<e, t, a>&)
  -> decltype(&std::endl<e,t>)
{ return std::endl<e,t>; }

template<class e, class t> //stream version
auto get_endl(const std::basic_ostream<e,t>&)
  -> decltype(&std::endl<e,t>)
{ return std::endl<e,t>; }

int main () {
  std::ostream& stream = std::cout;
  append_to_stream(stream,
                 get_endl(stream),
                 get_endl(stream));
}
Run Code Online (Sandbox Code Playgroud)