需要关于模板类实例化的帮助

Need help regarding Template class instantiation

本文关键字:实例化 帮助 于模板      更新时间:2023-10-16

让我用一个例子来说明我的问题:

template <typename T> class a{
public:
    T data;
    a():data(T()){}
    a(T temp): data(temp) {}
};

所以如果在main()中写入

a(30);
a("String");

因此,根据模板参数推导规则,它应该能够生成第一个临时类a<int>(30)

但是我的错误是:

在'('令牌

之前缺少模板参数

那么为什么会发生这种情况,这只适用于函数模板?

从实参中推导模板形参只适用于函数,不适用于。除非你知道类的类型,也就是它所有的模板形参,否则你甚至不知道这个类有哪些成员函数!

所以,如果你想直接构造一个对象,你总是需要说出模板参数:

a<int> x(30);

这里有一个小的思想实验来扩展上面的内容。假设我们有

template <typename T> class Foo;

,我们称之为Foo::somefunction(x);,其中x是某种类型。你会想,我像这样声明somefunction():

template <typename T> class Foo
{
  static void somefunction(const T & x);
};

所以很明显Tx的类型是相同的。但是现在假设我有一个专门化:

template <> class Foo<char>
{
  static void anotherfunction(double x);
};

Foo<char>甚至没有函数somefunction(),所以表达式Foo::somefunction(x)甚至没有到我可以查找参数的阶段!

通常的解决方法是创建一个免费的帮助函数来构造你的对象:
template <typename T> a<T> make_a(const T & x) { return a<T>(x); }

由于这是一个函数模板,它的形参可以推导:

make_a(30);      // type a<int>
make_a("hello"); // type a<char[6]>

构造函数不是模板,而是类本身是模板。因此,当您编写a(30)时,不能为类模板推导模板参数 !

如果存在构造函数模板,则编译器可以推导出模板化构造函数的模板实参。例如:

template <typename T> class A{
public:
    template<typename U>
    A(const U &): {}   //note : it's a constructor template
};
A<char>  obj(30); //U is deduced as int

在上面的例子中,只能推导出U,您仍然需要提供T。它因为

  • U是构造函数模板的模板参数。模板参数推导可以在这种情况下完成。
  • T是类模板的模板参数。模板参数推导不能在这里进行。

您仍然需要将临时声明为,例如a<int>(30)

你不能从构造函数的参数中推断出类模板的参数——很遗憾。

模板类型推断只发生在模板函数中。您需要为模板类实例化指定参数。您可以使用函数模板来推断模板参数并返回适当的类型。在c++ x中,你可以使用auto来保存实例。不能在我的手机上为您轻松编写示例代码!