我有这些功能:
template<class Route, bool enabled=true>
inline void addRoute() {
if(!enabled) return;
routes.push_back(Route({}, {}));
}
template<class Route, bool enabled=true, class... Args>
inline void addRoute(Args&&... args, std::vector<LogLevel>&& levels_ = {},
std::vector<String>&& categories_={}) {
if(!enabled) return;
if(!removeLowerLevels(levels_)) return;
routes.push_back(Route(std::forward<Args>(args)..., levels_, categories_));
}
该函数应该传递“main”参数(任何Route类的levels_和categories_);如果其中一个派生类中有任何其他参数,也可以将其传递给路径。我希望这个功能以多种方式工作:
//1. takes no additional arguments
addRoute<ConsoleLogRoute, DEBUG>({LogLevel::Notice}, {"system"});
//2. Takes no additional or main arguments
addRoute<SomeCustomLogRoute>();
//3. Takes additional arguments but no main arguments
addROute<HtmlLogRoute>("textFile.html", HtmlLogRoute::MakeBulletLists);
//4. Takes any amount of additional arguments
addRoute<FileLogRoute>("filename.log", {LogLevel::Info}, {"application"});
1和2按预期工作。但是3和4无法编译:
Error: Candidate function requires at most 2 arguments, but X were provided.
(X为3或4)
我通过提供Args
:
addRoute<FileLogRoute, true, String>("filename.log", {LogLevel::Info}, {"application"});
我的问题是:
如果不显式写变量typename,我该怎么办?与此printf example一样(取自here)。
答案 0 :(得分:2)
让我们看一个更简单的例子:
// declare something to call, just for filler.
int sum(int i) { return i ; }
template <class T, class... A> int sum(T v, A&&... vs) { return v + sum( vs... ) ; }
template < class... A >
int process( A&&... a, int val )
{
return sum( val, a... ) ;
}
int main()
{
int i ;
i= process( 10) ;
i= process( 10, 1 ) ; // fail
return 0 ;
}
通过将变量int val
放在变量模板参数之后,GCC和Clang都将A&&
的参数列表设置为零。如果您交换头寸,它可以正常工作。所以基本上A&&...
非贪婪,如果你把任何其他参数放在它之后,它默认为空。
正如您所发现的,通过明确声明类型,它将起作用,因此在这种情况下
i= process<int>( 10, 1 )
会起作用。