为什么模板类型的初始化需要重复变量的类型?

时间:2009-11-02 19:50:38

标签: c++ templates

假设我有一个对象,其成员变量属于某种模板类型。所以,在课堂宣言中,会出现这样的情况:

// This is just the declaration of bar which is a member of some class.
templatizedType<Foo> bar; 

现在,当我想初始化bar时,我为什么要做

 // This is the initialization. Note that I am assuming that templatizedType has a 
 // constructor that takes an argument of type T*. Presumably, this is happening 
 // somewhere inside whatever class has declared bar as a member.
templatizedType<Foo> bar(new Foo());

而不是简单

bar(new Foo());
编辑(试图澄清):基本上,在我看来,条形的类型(包括参数化类型)已经在它作为类的成员的声明中拼写出来,因此在初始化时不需要重复。

如果这一切都没有意义,请告诉我(我发现这主要是通过反复试验和IRC上的一些有帮助的人,所以如果我对这里发生的事情的理解是错误的,那么帮助也是如此非常感谢。)

5 个答案:

答案 0 :(得分:2)

templatizedType<Foo> bar;

调用默认构造函数,而

templatizedType<Foo> bar( new Foo() );

调用构造函数,将Foo *作为第一个参数 要构造一个对象,您必须编写该类型。 这就是原因,

bar( new Foo() )

不调用templatizedType的构造函数,而是调用已构造的该类型对象的方法。例如,这种方法可以是:

void operator()( Foo* )

希望这会有所帮助..

答案 1 :(得分:1)

由于C ++是一种强类型语言,它想确保你所指的这个“bar”事物确实是可以接受“new Foo()”因此你需要给它一个类型,就像在行:

templatizedType<Foo> bar(new Foo());

另外,如果你只是说

bar(new Foo());

谁能说这不是函数bar()vs变量声明?

答案 2 :(得分:0)

您确定不只是将名称bar重载为构造函数中的局部变量,即如果您的类被调用A,那么您正在做什么

A::A()
{
    templatizedType<Foo> bar(new Foo());
}

而不是

A::A()
    : bar(new Foo())
{
}

答案 3 :(得分:0)

原因是因为解析模板化函数的重载已经很困难,而不必处理模板的部分特化和模板成员的肮脏(我知道这听起来令人困惑。那是因为它令人困惑。)< / p>

基本上,确定当你拥有这个时要打电话的内容:

void foo (int i);
template <typename T> void foo (T t);
当你拥有这个时,

比弄清楚要打电话要容易得多:

template <typename T> class foo {
    foo (T t);
    template <typename U> foo (U u);
};

构造函数的可能性太大了,无法通过一些启发式来解决,就像为函数模板所做的那样,所以标准根本就没有尝试(在我看来,这是正确的调用)。相反,模板化类型可以提供make_****函数(make_pair浮现在脑中),它们充当模板化构造函数。

答案 4 :(得分:0)

我认为你最好希望发表一个声明,例如

TemplatizedType<> bar(new Foo());

但这种推论不会发生。我想最好的理由是编译器首先需要知道要实例化哪个TemplatizedType,然后才能检查它们是什么构造函数。

使用C ++ 0x,您可以将推断模板参数的make_xxx函数与 auto 关键字结合使用:

auto bar = make_templatized_type(new Foo());