【发布时间】:2012-04-18 10:38:03
【问题描述】:
所以,我试图写一个这样的函数:
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...);
}
然后这样称呼它:
append_to_stream(stream,
std::endl,
std::endl);
但这不起作用。我收到一个错误,提示函数“参数过多”。我已经把它缩小到我知道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>]’
更新
试图让编译器推断出正确的模板参数@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>;
}
但是,这不会编译。
错误:
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’
任何想法为什么?为了编译这个,我添加了using namespace std;
【问题讨论】:
-
你用的是什么编译器? IIRC 一些编译器在一段时间内遇到了这样的递归问题。
-
std::endl不是函数,而是模板。 -
我很困惑您的错误消息显示您的流是
std::string?这和你说的不符…… -
@Robᵩ:编译器指的是
endl的可能特化集,它们形成了一组重载函数。由于函数参数类型是通用的,因此其中任何一个都会匹配,并且编译器无法从中选择。如果参数具有特定类型(如ostream&(*)(ostream&)),则编译器可以选择具有该类型的特化(endl<char, char_traits<char>>);这就是ostream << endl有效的原因。 -
@MooingDuck 这是一个泄漏抽象的例子。我试图将示例简化为基本要素 - 我错误地将
std::string参数留在其中。真正的函数由创建fstream的函数包装。
标签: c++ c++11 variadic-templates