首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查找模板参数的typeid

查找模板参数的typeid
EN

Stack Overflow用户
提问于 2011-04-20 15:15:35
回答 3查看 3.3K关注 0票数 1

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

代码语言:javascript
复制
#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;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-20 15:21:53

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

代码语言:javascript
复制
List<int> kk( List<int> );

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

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

代码语言:javascript
复制
template <typename T>
class List {
public:
   List() {}
   template <typename U>
   List( List<U> const & ) {} // prefer const& as that will avoid unnecessary copying
};

现在你可以写下:

代码语言:javascript
复制
List<int> l = List<int>(); // this will call List<int>::List( List<int> const & )

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

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

代码语言:javascript
复制
List<int> l = List<double>();

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

票数 6
EN

Stack Overflow用户

发布于 2011-04-20 15:32:52

以及David确定的“最令人烦恼的解析”:

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

所以:

代码语言:javascript
复制
#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);
}
票数 2
EN

Stack Overflow用户

发布于 2011-04-20 15:37:45

你想用这句话做什么:

代码语言:javascript
复制
List <int> kk (List <int>);

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

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

代码语言:javascript
复制
List() {}

添加到类中,并写道:

代码语言:javascript
复制
List<int> kk((List<int>());

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

代码语言:javascript
复制
List<int> a;
List<int> b(a);

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5726775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档