2011-04-20 33 views
0

在构造函数的定义print语句不打印它的typeid的,没有构造函数调用正确的主?我知道我在这里错过了一些观点,请指出。找到一个模板参数

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

回答

6

代码中有几个错误可能你没有意识到。

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

这条线是不能定义一个变量,而是一个功能,需要一个List<int>作为参数,并返回一个List<int>,以便有效地将不调用任何构造函数的声明。即所知的最让人头疼的 - 解析(你可以看看不同的版本的它在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>(); 

由于类型实际上不同,编译器不能拷贝构造,会发现所提供的模板构造函数是最好的超载候选人并称之为。

+0

谢谢,但什么是SO?我经常看到有人提到这一点。 – 2011-04-20 07:24:00

+2

StackOverflow:P – Adam 2011-04-20 07:25:01

+0

@Adam哦,谢谢,让我搜索 – 2011-04-20 07:26:24

2

除了“最棘手的解析”由大卫认定:

  • 你需要有至少一个以上的构造函数来创建要传递给拷贝构造函数的原始列表对象,
  • 你需要改变参数类型,以便有调用模板拷贝构造函数:因为是你,而不是匹配隐含声明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); 
} 
+0

(David在我写这篇文章的时候继续覆盖同一个领域:-)) – 2011-04-20 07:34:16

+0

也非常感谢你,但是我的愚蠢之处在于我认为我可以通过**这个**指针作为模板参数: rolleyes: – 2011-04-20 08:33:15

1

什么是你想用这个语句来完成:

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

(它实际上声明的函数,而不能是什么,但 函数声明)

为了看到复制构造函数的输出,你必须调用警察 y构造函数莫名其妙。这意味着有一个 对象进行复制。以下给出的代码不可能: 给定:由于您明确声明了构造函数, 编译器将不会提供默认构造函数,并且您没有其他创建对象的构造函数。所以你有 没有办法创建任何东西来复制。如果添加

List() {} 

到类,并写上:

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

,你可能会得到一些东西,但是编译器被允许在这里的Elid 的副本,因此更可能会出现不输出。试试:

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

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

+0

谢谢,:redface:我忘记了所有关于复制构造函数的问题。 – 2011-04-20 08:34:37

相关问题