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)
| 归档时间: |
|
| 查看次数: |
1383 次 |
| 最近记录: |