【问题标题】:Why does VC++ allow an instance of a template class without full template parameters?为什么 VC++ 允许没有完整模板参数的模板类的实例?
【发布时间】:2014-06-23 09:02:00
【问题描述】:

在VC++ 2013的C++头文件memory中,我发现类unique_ptr的定义如下:

template<class _Ty, class _Dx> // = default_delete<_Ty>
class unique_ptr
{
    ...
};

让我困惑的是:模板参数没有默认类型,这是 C++11 标准所要求的。 (见here

但是,我可以编译以下代码而不会出现任何警告或错误:

#include <memory>

using namespace std;

int main()
{
    unique_ptr<int>(new int); // Should be OK! ???
    // rather than unique_ptr<int, default_delete<int>>(new int);
}

为什么?

【问题讨论】:

    标签: c++ templates visual-c++ c++11 unique-ptr


    【解决方案1】:

    默认参数在前向声明中指定:

    // [memory:24]
    _STD_BEGIN
     #if _HAS_CPP0X
    template<class _Ty>
        struct default_delete;
    
    template<class _Ty,
        class _Dx = default_delete<_Ty> >
        class unique_ptr;
     #endif /* _HAS_CPP0X */
    
     // [...]
     // [memory:1276]
    // TEMPLATE CLASS unique_ptr SCALAR
    template<class _Ty,
        class _Dx>  // = default_delete<_Ty>
        class unique_ptr
            : private _Unique_ptr_base<_Ty, _Dx,
                is_empty<_Dx>::value
                    || is_same<default_delete<_Ty>, _Dx>::value>
        {   // non-copyable pointer to an object
    

    这是有效的,就像在定义函数之前为函数声明默认参数是有效的一样,例如

    void foo(int x = 5);
    void foo(int x) { /* ... */ }
    

    [C++11: 14.1/10]: 可与模板声明或定义一起使用的默认 template-arguments 集合是通过合并定义中的默认参数(如果在范围内)和范围内的所有声明获得的与默认函数参数相同的方式(8.3.6)。 [示例:

     template<class T1, class T2 = int> class A;
     template<class T1 = int, class T2> class A;
    

    等价于

     template<class T1 = int, class T2 = int> class A;
    

    ——结束示例]

    【讨论】:

      【解决方案2】:

      我可以访问 VS 2012,这是我看到的:

      #if _HAS_CPP0X
      template<class _Ty>
          struct default_delete;
      
      template<class _Ty,
          class _Dx = default_delete<_Ty> >
          class unique_ptr;
      #endif /* _HAS_CPP0X */
      

      因此声明具有默认模板参数。作为 C++ 中的一般规则,如果在前向声明中指定了默认参数,则无需重复定义默认参数。我记得如果你在声明和定义中都指定了默认参数值,编译器会发出错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-05-04
        • 2013-11-27
        • 2014-07-27
        • 1970-01-01
        • 1970-01-01
        • 2013-10-02
        相关资源
        最近更新 更多