可以推断出左值引用非类型模板参数吗?

时间:2016-02-01 20:45:10

标签: c++ templates c++11 language-lawyer lvalue

我有以下代码,我无法开始工作:

struct foo {};
foo foo1 = {};

template <foo& F>
class FooClass {};

template <foo& F>
void foobar(FooClass<F> arg) {
}

int main() {
    FooClass<foo1> f;
    foobar(f);
}

错误是:

  

main.cpp:14:5:错误:没有匹配函数来调用&#39; foobar&#39;

     

注意:候选模板被忽略:替换失败:推断出的非类型模板参数与其相应的模板参数的类型不同(&#39; foo&#39; vs&#39; foo&amp;&#39 ;)

是否可能推断 lvalue 参考模板参数?如果是这样,应该怎么做?

1 个答案:

答案 0 :(得分:6)

这正是CWG 2091

所涵盖的
  

根据14.8.2.5 [temp.deduct.type]第17段,

     
    

如果P的表单包含<i>,并且相应值A的类型与i的类型不同,则扣除     失败。

  
     

这给出了一个例子的错误结果:

template<int &> struct X;
template<int &N> void f(X<N>&);
int n;
void g(X<n> &x) { f(x); }
     

此处PX<N>,其中包含<i>i的类型为int&。   来自A的相应值为n,它是类型的glvalue   int。大概这应该是有效的。

     

我认为这条规则意味着说,

     
    

如果P的表单包含<i>,且i的类型与模板的相应模板参数的类型不同     由封闭的 simple-template-id 命名,扣除失败。

  

如@dyp所述,[temp.deduct.type]/17应该更宽容。在您的示例中,FooClass<F>F)中的参数没有引用类型 - 它是类型foo的左值。 FooClass的模板参数是参考。 DR去年解决了。