【发布时间】:2011-05-13 20:21:03
【问题描述】:
我有一个可变参数函数,我想在第一个参数类型上重载。
void write( void ) { }
void write( std::ostream& ) { }
template< typename Head, typename... Rest >
void write( std::ostream& out, Head&& head, Rest&&... rest )
{
out << head;
write( out, std::forward<Rest>(rest)... );
}
template< typename... Args >
void write( Args&&... args )
{
write( std::cout, std::forward<Args>(args)... );
}
但是这些函数的行为并不像预期的那样。
write( "## to cout ##" ); // printed to stdout as expected
write( std::cerr, "## to cerr ##" ); // printed to stderr as expected
std::ostringstream oss;
write( oss, "## to string ##" ); // error here
// '0x7fff9db8## to string ##' is printed to stdout!
这是怎么回事?
为什么重载分辨率不选择我想要的功能?
有没有办法在没有大量元编程的情况下做到这一点? (我可以使用 std::is_convertible 解决它,但解决方案比我上面显示的简单代码大得多)。
【问题讨论】:
-
为什么需要最后一个模板特化?没有那个问题就会消失。
-
@Diego,如果调用者未提供 ostream 对象,则最后一个特化 (
write(args)) 将std::cout作为第一个参数。
标签: c++ c++11 variadic-templates overload-resolution