【问题标题】:C++ When template argument deduction failsC++ 当模板参数推导失败时
【发布时间】:2011-07-28 12:54:57
【问题描述】:

为什么 C++ 不能确定我打算使用这种语法创建 unique_ptr<A>? (a 之前已声明为 unique_ptr<A>

a = unique_ptr(new A());

必须包含<A> 似乎非常多余。这适用于我使用的大多数函数模板,为什么不使用 unique_ptr?

编辑:C++ 现在支持 make_unique,没有冗余。

【问题讨论】:

    标签: c++ templates arguments


    【解决方案1】:

    std::unique_ptrclass 模板,而不是 function 模板。参数推导只发生在 function 模板,而不是 class 模板。

    一个常用的技巧是写一个函数模板,创建一个实例化类模板类型的对象,例如:

    template <typename T>
    std::unique_ptr<T> make_unique_ptr(T* ptr) 
    {
        return std::unique_ptr<T>(ptr);
    }
    

    不过,对于std::unique_ptr,我会避免这样做:std::unique_ptr 对象应该直接获取动态分配对象的所有权,因此不需要这样做。你的代码应该写成:

    std::unique_ptr<A> a(new A());
    

    或者,如果a 已经存在,则可以调用reset()

    a.reset(new A());
    

    至于为什么类型推导对实例化类模板不起作用,请考虑以下示例:

    template <typename T>
    struct X
    {
        template <typename U> X(U) { }
    };
    

    T 不可能从构造函数的调用中推导出来。即使在构造函数的参数类型为T 的“更简单”的情况下,由于构造函数可能被重载,因此仍然存在问题。

    【讨论】:

    • 很好的答案,就像我想的 make_pair 一样。类模板不能进行模板参数推导是否有任何语言原因?
    • @James:逻辑错误。您展示的示例或您正在谈论的案例可以被断然拒绝,将它们标记为“非推断”上下文。那么问题来了:模板实参可以推导出来的情况,比如只有一个参数为T的构造函数?
    • @Nawaz:我描述的案例涵盖了绝大多数类模板,包括std::unique_ptr
    • @James:确实如此。但是即使可以推导出模板参数推导也不会发生。因此,在我看来,您的解释没有任何意义,因为即使由于构造函数重载而没有“麻烦”,也不会发生参数推导。
    • @Nawaz:该功能不存在。如果它确实存在,它只会在极少数情况下可用,并且不会启用任何特别有趣的功能,因此添加该功能的成本(增加参数推导规则的复杂性)是不值得的。你不同意吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 2022-01-06
    相关资源
    最近更新 更多