隐式找到模板变量typename

时间:2014-01-20 17:19:03

标签: c++ c++11

我有这些功能:

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)。

1 个答案:

答案 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 )

会起作用。