1

构造函数定义中的 print 语句没有被打印出来,是不是构造函数在 main 中调用正确?我知道我在这里遗漏了一些观点,请指出。

#include <iostream>
#include <typeinfo>

template <typename T> class List
{
    public: 
        template <typename T2> List (List<T2> const&);
}; 

template <typename T> template <typename T2> List <T> :: List (List <T2> const&) 
{
    std :: cout << "\nType name:" << typeid (T2).name();
}

int main ()
{
    List <int> kk (List <int>);
    return 0;
}
4

3 回答 3

6

您的代码中有几处您可能不知道的错误。

List<int> kk( List<int> );

该行不是变量定义,而是以 aList<int>作为参数并返回 a的函数的声明List<int>,因此实际上不会调用任何构造函数。这被称为最令人烦恼的解析(您可以通过在 SO 或C++ FAQ lite中搜索来查看它的不同版本)

第二个问题是您不可能创建实例化类型的任何实例List,原因是您提供的唯一构造函数是一个模板化构造函数,它接受第二个List<U>作为参数。这有效地禁用了默认构造函数,因此创建 a 的唯一方法List<T>是已经拥有 a List<U>,这是不可能的。您可以添加默认构造函数:

template <typename T>
class List {
public:
   List() {}
   template <typename U>
   List( List<U> const & ) {} // prefer const& as that will avoid unnecessary copying
};

现在你可以写:

List<int> l = List<int>(); // this will call List<int>::List( List<int> const & )

然而,这仍然不会调用你想要的构造函数。原因有点晦涩,但是在复制构造模板的元素时,编译器不会使用模板化构造函数。在上面的代码中,它将通过执行方法的成员方式复制构造函数并调用生成的构造函数来隐式定义复制构造函数。这意味着在您想要提供模板化构造函数的大多数情况下,您还想提供非模板化复制构造函数。

要实际调用该构造函数,您必须提供不同的类型:

List<int> l = List<double>();

由于类型实际上不同,编译器无法复制construct,会发现提供的模板化构造函数是最好的重载候选并调用它。

于 2011-04-20T07:21:53.210 回答
2

以及 David 确定的“最令人头疼的解析”:

  • 您至少需要一个构造函数来创建要传递给复制构造函数的原始 List 对象,
  • 您需要更改参数类型才能调用模板化的复制构造函数:因为您将匹配隐式声明的List(const List&)复制构造函数。

所以:

#include <iostream>

template <typename T>
struct X
{
    X() { std::cout << "X()\n"; }

    // implicitly like this anyway...
    // X(const X& rhs) { std::cout << "X(X&)\n"; }

    template <typename U>
    X(const U& u) { std::cout << "U\n"; }
};

int main()
{
    X<int> x;
    X<int> y(x);
}
于 2011-04-20T07:32:51.927 回答
1

你想用这个语句做什么:

List <int> kk (List <int>);

(它实际上声明了一个函数,只能是函数声明。)

为了查看复制构造函数的输出,您必须以某种方式调用复制构造函数。这意味着要复制一个对象。这对于您给出的代码是不可能的:由于您明确声明了构造函数,编译器将不会提供默认构造函数,并且您没有其他构造函数可以用来创建对象。因此,您无法创建任何要复制的内容。如果你添加一个

List() {}

上课,然后写:

List<int> kk((List<int>());

,你可能会得到一些东西,但是编译器可以在这里省略副本,所以更有可能没有输出。尝试:

List<int> a;
List<int> b(a);

或者只是将您的输出放在默认构造函数中。

于 2011-04-20T07:37:45.430 回答