查找模板参数的typeid

Aqu*_*irl 0 c++ templates typeid most-vexing-parse

构造函数定义中的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;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 6

您可能没有意识到代码中存在一些错误.

List<int> kk( List<int> );
Run Code Online (Sandbox Code Playgroud)

该行不是变量定义,而是声明一个带有List<int>as参数并返回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
};
Run Code Online (Sandbox Code Playgroud)

现在你可以写:

List<int> l = List<int>(); // this will call List<int>::List( List<int> const & )
Run Code Online (Sandbox Code Playgroud)

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

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

List<int> l = List<double>();
Run Code Online (Sandbox Code Playgroud)

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

  • StackOverflow:P (2认同)