在使用 gcc7 测试 C++17 演绎指南行为时,我发现这个例子失败了:

template<class T>
struct S{
  S(T&& v){}
};
int i=10;
auto v = S(i);

根据我从 cpp reference 中读到的内容,我认为 v 应该是 S<int &> 类型。尽管如此,gcc7 没有编译这段代码,提示 int& 不能绑定(bind)到 int &&(通用引用机制失败)。

所以我的问题是:
  • gcc7 是否应该将 v 推断为 S<int&> 类型?
  • 工作草案标准中哪里描述了自动扣除指南?
  • 最佳答案

    [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] :



    因此,这个 T&& 而不是 转发引用。它是对 T 的右值引用。所以对左值(在我们的例子中, S(i) )的推导失败。 gcc 在这里拒绝您的代码是正确的。

    如果你想让类模板参数起到转发引用的作用,你需要添加一个推导指南:
    template <class T> S(T&& ) -> S<T>;
    

    关于c++ - 隐式模板推导指南能否推导出引用类型?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43521137/

    10-11 00:49