为什么我不能使用 std::unique_ptr 作为"模板<class>类"参数?

Why can't I use std::unique_ptr as a "template<class> class" argument?

本文关键字:模板 lt class 参数 gt 作为 不能 std ptr unique 为什么      更新时间:2023-10-16

此代码:

#include <memory>
template <template <typename> class Ptr>
class A { Ptr<int> ints; };
using B = A<std::unique_ptr>;

产生以下错误(GCC 6.3(:

a.cpp:6:28: error: type/value mismatch at argument 1 in template parameter list for ‘template<template<class> class Ptr> class A’
using B = A<std::unique_ptr>;
^
a.cpp:6:28: note:   expected a template of type ‘template<class> class Ptr’, got ‘template<class _Tp, class _Dp> class std::unique_ptr’

现在,我可以解决这个问题,比如:

template <typename T>
using plugged_unique_ptr = std::unique_ptr<T>;
using B = A<plugged_unique_ptr>;

但为什么我必须这样做?我的意思是,为什么编译器不愿意用默认值"插入"std::unique_ptr的第二个模板参数,并允许std::unique_ptr用作A的模板参数?

因为模板模板参数需要精确匹配。这意味着默认模板参数在这里不相关。请注意,将模板-模板参数扩展到两个模板参数只会在偶然的情况下起作用:一个实现可以添加比标准定义的更多的模板参数,有些实现在围绕std容器的SFINAE的情况下经常这样做。

这也是我通常建议不要使用任何模板-模板参数的主要原因,而应该使用简单的模板typename。如果您需要访问嵌套的模板类型,请在第行提供内部访问器,例如value_type或外部访问器,如tuple_element,以便在模板内访问这些类型。


注意:这在C++17中显然发生了变化,那里的匹配不再精确,但稍微放松但更复杂。尽管如此,我还是建议一般不要使用模板-模板参数。

std::unique_ptr有第二个带有默认值的模板参数,因此template <typename> class Ptrstd::unique_ptr不匹配

template <typename...> class Ptr将工作

cppreference

正如@HolyBlackCat所建议的,我们不再需要对C++17使用任何变通方法,OP的代码确实可以编译(coliru.com(。

GCC 6.3.0默认编译C++14代码,不应用此语言语义更改。