c++ - 查找模板参数的 typeid

标签 c++ templates typeid most-vexing-parse

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

#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;
}

最佳答案

您的代码中有一些您可能没有意识到的错误。

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

那一行不是一个变量定义,而是一个接受 List<int> 的函数的声明。作为参数并返回 List<int> ,这样实际上就不会调用任何构造函数。这就是众所周知的most-vexing-parse(您可以通过在 SO 或 C++ FAQ lite 中搜索来查看它的不同版本)

第二个问题是您不可能创建 List 的实例化类型的任何实例。 ,原因是您提供的唯一构造函数是一个模板化构造函数,它需要第二个 List<U>作为论据。这有效地禁用了默认构造函数,因此创建 List<T> 的唯一方法是已经有了一个 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>();

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

关于c++ - 查找模板参数的 typeid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5726775/

相关文章:

c++ - 带有 lambda 删除器的 Unique_ptr

c++ - 在 C++ 中利用 RTTI 的实际用途

c++ - 如何提高与 std::vector 共享内存的数据映射(Eigen::Map)矩阵的 GEMM 性能?

c++ - 在 C++ 中链接对临时对象的调用

c++ - 如何使用 pack 作为模板参数实例化专门的模板类?

C++ 模板帮助

c++ - 如何预测具有符号数字类型的东西?

c++ - 在 C++ 中获取类实例的名称?

c++ - ifstream 不占用内存的最佳读取方式

c++ - Dijkstra 的 - 队列