2017-01-14 175 views
1

当我想将可变参数模板参数包分为两部分时,我遇到了这个问题,第一部分包含除最后一部分以外的所有元素,第二部分仅包含最后一部分。一个简单的实现,它来到我的脑海,在下面的例子中invoke1功能:Variadic模板类型扣除

template <typename... Ts> 
void invoke1(Ts... ts, int param) { 
} 

template <typename... Ts> 
void invoke2(int param, Ts... ts) { 
} 

int main() {  
    invoke1(1); // this works 
    invoke2(1); // this works 

    invoke1(1, 2, 3); // this does not work 
    invoke1<int, int>(1, 2, 3); // this works 
    invoke2(1, 2, 3); // this works 

    return 0; 
} 

为什么当第一次指定的模板参数包模板参数不推导出invoke1?类型扣除会产生歧义吗?

回答

2
template <typename... Ts> 
void invoke1(Ts... ts, int param) { 
} 

首先,为什么

invoke1<int, int>(1, 2, 3); 

工作?上面明确指定了类型,所以不需要类型扣除。该模板实例化为:

void invoke1(int, int, int); 

因此与(1, 2, 3)的呼叫现在变得完全有效。

另一方面,如果不明确指定类型,编译器无法知道参数包的结束位置。 它是invoke1(int, int, int, int);invoke1(int, int, int);

现在,你会说:“不能只取最后一个给定的参数,并在它之前结束参数包?”。那么,答案是没有

invoke2另一方面工作正常,因为它清楚参数包开始和结束的位置。作为一个经验法则,总是把参数包放在最后。

+0

>现在,你会说:“不能只取最后一个给定的参数,并在它之前结束参数包?”。那么,答案是否定的。 为什么不回答?这是我的主要问题。 – Jodebo

+0

@Jodebo因为这是功能如何指定和标准化。 – DeiDei

+0

但恕我直言标准很多事情是由那它就可以工作“的方式。我的问题是,为什么编译器不能推断模板参数?什么是反对它的原因?它会在类型扣除等方面造成含糊之处吗?还是仅仅是语言缺陷,没有人提交论文? – Jodebo