为什么VC ++允许没有完整模板参数的模板类实例?

时间:2014-06-23 09:02:01

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

在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);
}

为什么?

2 个答案:

答案 0 :(得分:4)

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

// [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;
     

-end example]

答案 1 :(得分: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 ++中的一般规则,如果在前向声明中指定了default参数,则定义不需要重复默认参数。我记得如果在声明和定义中都指定了默认参数值,编译器会发出错误。

相关问题