C++模板函数中,如果是可变参数列表,可以设置默认参数嘛

不能,你要利用一些语法把调用改成这样:print({1_fuck, shit, "bitch"}, std::cunt);

■网友
#include \u0026lt;iostream\u0026gt;#include \u0026lt;type_traits\u0026gt;void print_( std::ostream\u0026amp; os ){}template\u0026lt;typename T\u0026gt;void print_( std::ostream\u0026amp; os, T\u0026amp;\u0026amp; t ){ os \u0026lt;\u0026lt; std::forward\u0026lt;T\u0026gt;(t);}template \u0026lt;class T,class ...Args\u0026gt;void print_( std::ostream\u0026amp; os, T\u0026amp;\u0026amp; head, Args\u0026amp;\u0026amp;... rest ){ print_( os, std::forward\u0026lt;T\u0026gt;(head) ); os \u0026lt;\u0026lt; ", "; print_( os, std::forward\u0026lt;Args\u0026gt;(rest)... );}void print( void ){ print_( std::cout );}template\u0026lt;class First\u0026gt;void print( First\u0026amp;\u0026amp; first){ if constexpr( std::is_convertible\u0026lt;First,std::ostream\u0026amp;\u0026gt;::value ) print_( std::forward\u0026lt;First\u0026gt;(first) ); else print_( std::cout, std::forward\u0026lt;First\u0026gt;(first) );}template\u0026lt;class First,class... Args\u0026gt;void print( First\u0026amp;\u0026amp; first, Args\u0026amp;\u0026amp;... rest ){ if constexpr( std::is_convertible\u0026lt;First,std::ostream\u0026amp;\u0026gt;::value ) print_( std::forward\u0026lt;First\u0026gt;(first), std::forward\u0026lt;Args\u0026gt;(rest)... ); else print_( std::cout, std::forward\u0026lt;First\u0026gt;(first), std::forward\u0026lt;Args\u0026gt;(rest)... );}#include \u0026lt;sstream\u0026gt;using namespace std;int main( void ){ print(); print( 1, \u0026#39;\\u0026#39; ); print( 1, 2, \u0026#39;\\u0026#39; ); print( std::cout ); print( std::cout, 1, \u0026#39;\\u0026#39; ); print( std::cout, 1, 2, \u0026#39;\\u0026#39; ); ostringstream oss; print( oss ); print( oss, 1, \u0026#39;\\u0026#39; ); print( oss, 1, 2, \u0026#39;\\u0026#39; ); cout \u0026lt;\u0026lt; oss.str();}
■网友
不会产生歧义的情况下,可以实现将默认参数作为可变参数列表最后一个参数,不过代码稍微有一些麻烦,需要一个中间过程判断最后一个参数是不是ostream类型——如果是的话,就将其调整到前面来。
首先定义一个PrintImpl类,里面放题主原来的版本:
struct PrintImpl { template \u0026lt;typename OStream, typename T\u0026gt; static inline void Print(OStream \u0026amp;out, const T \u0026amp;n) { out \u0026lt;\u0026lt; n \u0026lt;\u0026lt; " " \u0026lt;\u0026lt; std::endl; } template \u0026lt;typename OStream, typename T, typename ...Args\u0026gt; static inline void Print(OStream \u0026amp;out, const T \u0026amp;head, const Args \u0026amp;...rest) { out \u0026lt;\u0026lt; "parameter " \u0026lt;\u0026lt; head \u0026lt;\u0026lt; std::endl; Print(out, rest...); }};然后是中间过程:
// 默认使用std::couttemplate \u0026lt;typename LastT, typename Enable = void\u0026gt;struct PrintDispatcher { template \u0026lt;typename ...Args\u0026gt; static inline void Print(Args \u0026amp;\u0026amp;...args) { PrintImpl::Print(std::cout, args...); }};// 特化:最后一个参数是std::ostream类型。// 方法是将参数打包成一个tuple,然后用compile-time sequence将最后一个参数调到最前面。// 这里std::index_sequence之类的是C++14开始的特性,不过C++11下面也可以很方便地实现。template \u0026lt;typename LastT\u0026gt;struct PrintDispatcher\u0026lt; LastT, std::enable_if_t\u0026lt;std::is_base_of\u0026lt;std::ostream, LastT\u0026gt;::value\u0026gt;\u0026gt; { template \u0026lt;std::size_t last, typename Tuple, std::size_t ...indices\u0026gt; static inline void PrintTuple(Tuple \u0026amp;\u0026amp;tp, std::index_sequence\u0026lt;indices...\u0026gt; \u0026amp;\u0026amp;seq) { PrintImpl::Print(std::get\u0026lt;last\u0026gt;(tp), std::get\u0026lt;indices\u0026gt;(tp)...); } template \u0026lt;typename ...Args\u0026gt; static inline void Print(Args \u0026amp;\u0026amp;...args) { constexpr std::size_t last_index = sizeof...(args) - 1; PrintTuple\u0026lt;last_index\u0026gt;( std::forward_as_tuple(args...), std::make_index_sequence\u0026lt;last_index\u0026gt;()); }};


推荐阅读