[英]Why can't I use std::unique_ptr as a “template<class> class” argument?
This code: 这段代码:
#include <memory>
template <template <typename> class Ptr>
class A { Ptr<int> ints; };
using B = A<std::unique_ptr>;
yields the following error (with GCC 6.3): 产生以下错误(使用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’
Now, I can work around this, like so: 现在,我可以解决这个问题,就像这样:
template <typename T>
using plugged_unique_ptr = std::unique_ptr<T>;
using B = A<plugged_unique_ptr>;
but why do I have to? 但为什么我要这样做? I mean, why isn't the compiler willing to "plug" the second template parameter of
std::unique_ptr
with its default value and allow std::unique_ptr
to be used as a template argument to A
? 我的意思是,为什么编译器不愿意使用其默认值“插入”
std::unique_ptr
的第二个模板参数,并允许std::unique_ptr
用作A
的模板参数?
Because template template parameters need to match exactly. 因为模板模板参数需要完全匹配。 This means the default template argument is not relevant here.
这意味着默认模板参数在此处不相关。 Note that extending your template template argument to two template arguments will only work by chance: an implementation is permitted to add more template arguments than defined by the standard, and some often do in the case of SFINAE around std containers.
请注意,将模板模板参数扩展为两个模板参数只会偶然发生:允许实现添加比标准定义的模板参数更多的模板参数,有些参数通常在SFDAE的std容器周围。
This is also the prime reason I generally advise against using any template template arguments, and instead just use a plain template typename. 这也是我通常建议不要使用任何模板模板参数,而只是使用普通模板类型名称的主要原因。 If you need access to nested template types, provide internal accessors in line of eg
value_type
or external accessors such as tuple_element
to access these inside the template. 如果需要访问嵌套模板类型,请提供内部访问器(例如
value_type
或外部访问器(例如tuple_element
以访问模板内的这些访问器。
Note: This apparently has changed in C++17, where the matching is not exact anymore, but slightly relaxed yet more complicated. 注意:这显然在C ++ 17中发生了变化,其中匹配不再精确,但略微放松但更复杂。 Nevertheless, I would still advise against using template template parameters in general.
不过,我仍然建议不要使用模板模板参数。
std::unique_ptr
has a second template argument with a default so template <typename> class Ptr
doesn't match std::unique_ptr
std::unique_ptr
有一个默认的第二个模板参数,所以template <typename> class Ptr
与std::unique_ptr
不匹配
template <typename...> class Ptr
will work template <typename...> class Ptr
会起作用
As @HolyBlackCat suggests, we no longer have to use any workaround with C++17 - and OP's code does indeed compile (coliru.com). 正如@HolyBlackCat建议的那样,我们不再需要使用C ++ 17的任何解决方法 - 而且OP的代码确实可以编译 (coliru.com)。
GCC 6.3.0 compiles C++14 code by default and doesn't apply this language semantics change. GCC 6.3.0默认编译C ++ 14代码,不应用此语言语义更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.