嵌套模板参数
Nested template parameters
我已经开始阅读有关模板的文章,我发现智能指针使用双模板,如下所示:
template <class T>
class myclass
{
public:
template <class U>
myclass(U* q) { /* ... */ }
};
这是什么意思?我知道模板化函数会推断出U
,因为
myclass(new whatever(3));
U
将在哪里whatever*
.那么什么是T
?U
和T
之间有什么关系?
我很困惑...
上面的示例代码在T
和U
之间没有强加任何关系。
一个是传递给类模板的类型参数myclass
,另一个是传递给构造函数的推导类型。
但是,在您发现它的地方(可能std::shared_ptr
)它会变得更加有趣。
现在,在std::shared_ptr
中,构造函数的主体强加了一个要求,即U
是T
的后代类型。 该构造函数允许您从Derived*
创建std::shared_ptr<Base>
,同时在构造函数中知道它是从Derived*
构造的。
我们为什么要这样? 毕竟,Derived*
可以在构造函数之外转换为Base*
,那么为什么不直接采用T*
(又名Base*
)呢?
好吧,std::shared_ptr<T>
是将 3 件事捆绑在一起。 它是一个T*
,一个引用计数器和一个清理功能("删除器")。
当引用计数减少到 0 时,将调用清理函数。 默认情况下,清理函数调用指向对象的析构函数。
但是哪个析构函数? 好吧,调用的析构函数基于类型 U
,而不是 T
。 在构造时,编写一个知道静态类型的破坏函数U
。 这个销毁函数被带到该原始shared_ptr<T>
的所有副本中,所以即使它被销毁得很远,它仍然调用~U
而不是~T
。
如果T
有一个virtual ~T()
它不会做太多事情(事实上,相同的comdat 折叠或类似的技术将使它什么都不做),但如果它有一个非虚拟析构函数,shared_ptr
将调用正确的析构函数(假设该类型实际上是U
而不是某种派生的U
类型)。
shared_ptr
出于其他原因需要存储销毁函数(您可以传入自定义销毁函数),因此这不会产生很大的开销。
示例中,myclass
是一个模板类,构造函数myclass::myclass()
是一个模板方法。两者都必须被赋予一个类型,以便它们可以"正常工作",其中"给定"也可能意味着推断出该类型。
例如,myclass
实例的有效声明是
myclass<double> x(new int(3));
这里T = double
和U = int
(请注意,构造函数采用U*
)。U
和T
之间不需要有关系。
T
和 U
之间没有关系。您可以使用任何T
实例化myclass
,并使用任何参数调用构造函数,只要它是指针(在您的情况下):
class A {};
class B {};
myClass<A> x(new B()); // T == A, U == B
请注意,您不能显式指定U
,它只能从参数中推导出来。
考虑一个类模板:
template<typename T>
class Element
{
T _element;
public:
CopyFrom(T t);
};
如果要CopyFrom
任何未T
的类型怎么办。例如:
Element<int> a;
a.CopyFrom(10.0f);
在这里,只是为了理解int
float
转换是不可能的,只有CopyFrom
可以做到这一点(使用一些辅助函数,一些其他内部过载函数等) - 但为了避免任何数据丢失警告。因此,您需要类似以下内容:
a.CopyFrom<float>(10.0f);
在这里,您将参数类型指定为 float
- 编译器现在会很高兴。要使其工作,您需要CopyFrom
函数(方法)模板
public:
template<typename U>
CopyFrom(U t);
现在,a
属于 Element<int>
型,但CopyFrom
将是CopyFrom<float>
。显然,您无需使用 <float>
.
a.CopyFrom/*<float>*/(10.0f); // Element<int>::CopyFrom<float>(...);
- 嵌套参数包扩展失败
- 嵌套定义与定义的参数 C++
- 如何避免嵌套模板中的模板参数重复
- 重构模板类,该类将其嵌套类用作另一个类的模板参数
- 以嵌套类为参数的友元模板声明
- 是否可以指定 C++20 个模板化 lambda 来推断嵌套在参数中的类型?
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 嵌套模板类的模板类模板模板参数的专业化
- 不能使用嵌套结构中的联合元素作为 scanf() 的参数来存储所需的值
- 修改嵌套 lambda 中捕获的参数:gcc 与 clang?
- 声明嵌套在模板参数中的类型的变量?
- 将参考类型作为嵌套模板结构中的模板参数作为模板参数不起作用
- 模板嵌套类模板类作为与完全专业函数的参数
- C++ 17 可以处理嵌套的可变参数模板吗?
- 带有可变参数的嵌套宏在GCC中编译,但在MSVC中不编译
- 在C++中使用模板类的嵌套类作为模板模板参数
- 如何使用variadic参数包的嵌套模板类
- 如何在variadic模板中采用嵌套参数包
- 传递具有依赖嵌套参数类型的模板模板参数时出错
- 可变参数嵌套循环