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

mol*_*olf 11 c++ templates lvalue language-lawyer c++11

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

struct foo {};
foo foo1 = {};

template <foo& F>
class FooClass {};

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

int main() {
    FooClass<foo1> f;
    foobar(f);
}
Run Code Online (Sandbox Code Playgroud)

错误是:

main.cpp:14:5:错误:没有匹配函数来调用'foobar'

注意:候选模板被忽略:替换失败:推导出的非类型模板参数与其对应的模板参数('foo'vs'foo&')的类型不同

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

Col*_*mbo 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); }
Run Code Online (Sandbox Code Playgroud)

在这里,PX<N>,包含<i>.类型iint&.from的对应值An,类型的glvalue int.据推测这应该是有效的.

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

如果P具有包含的表单<i>,并且类型i与封闭的simple-template-id所指定的模板的相应模板参数的类型不同,则扣除失败.

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