在[over.match.class.deduct]规则是:
一组功能和功能模板形成包括:
- 对于由模板名指定为主类模板的每个构造中,如果模板被定义为具有以下属性的功能模板:
- 模板参数是类模板的模板参数,后面跟着模板参数米(包括默认模板参数)的构造函数,如果有的话。
- 函数参数的类型是构造函数的类型。
- 返回类型是由模板名称和模板参数指定的类模板特化,该模板参数对应于从类模板获得的模板参数。
我们集包括:
template <class T> // <-- the template parameters come from the class template
S<T> // <-- the return type is the class template specialization
foo(T&&); // <-- the types of the parameters are those of the constructor
我们进行重载像往常一样,它涉及到的模板扣除。 但是从[temp.deduct.call]:
甲转发参考是一个rvalue参照CV-不合格模板参数不代表类模板参数推导期间一个类模板(的模板参数([在.match.class.deduct]))。如果P是转发引用并且参数是左值,则使用类型“左值引用A”来代替类型推导中的A.
因此,这是T&&
不转发参考。这是一个参考T
的右值。因此,扣除左值(在本例中为S(i)
)失败。 gcc在这里拒绝你的代码是正确的。
如果你想在类模板参数用作转发引用,你将需要添加一个演绎指南:
template <class T> S(T&&) -> S<T>;
考虑到GCC版本7都尚未公布,也一定会错误。如果这是其中之一,我不知道。你有没有在C++ 17模式下用GCC 6试过它(GCC 6支持C++ 17的大部分)? –
扣除指南在GCC6中未实现。我只是想知道,如果它是cpp参考或GCC7是正确的,我不能自己juge,因为我没有找到标准的主题... – Oliv
请注意,cppreference包括这种情况。这是该页面的最后一个例子。 Cubbi和TC不要乱搞:-) – Barry