开发者

Why does initialization of a template type require a repeat of the type of the variable?

开发者 https://www.devze.com 2022-12-10 12:58 出处:网络
Suppose I have an object that has a member variable that is of some template type. So, in the declaration of the class, there would be something like this:

Suppose I have an object that has a member variable that is of some template type. So, in the declaration of the class, there would be something like this:

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

Now, when I want to initialize bar why do I have to do

 // 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());

instead of simply

bar(new Foo());

EDIT(trying to clarify): Essentially, it seems to me that the type of bar (including the parametrized type) is already spelled out in it's declaration as a member of the class and thus should not require a repeat upon initialization.

If none of this makes sense, let me know (I discovered this mostly through trial-and-error and some helpful people on IRC, so if my understanding of what is going on here is wrong, he开发者_开发技巧lp with that would also be greatly appreciated.)


templatizedType<Foo> bar;

calls the default constructor, while

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

calls the constructor taking a Foo* as first argument To construct an object, you have to write the type. That is why,

bar( new Foo() )

does not call the constructor of templatizedType, but instead calls a method on an already constructed object of that type. This method could be, for instance:

void operator()( Foo* )

hope this helps..


Since C++ is a strongly typed language, it wants to make sure that this "bar" thing you are referring to really is something that can accept "new Foo()" therefore you need to give it a type, as in the line:

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

Also if you just say

bar(new Foo());

Who is to say this isn't a function bar() vs a variable declaration?


Are you sure that you're not just overloading the name bar as a local variable in your constructor i.e. if your class is called A are you doing

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

instead of

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


The reason is because of the fact that resolving overloads to templated functions is difficult already, without having to deal with the nastiness that is partial specialization and template members of templates (I know it sounds confusing. That's because it's confusing.)

Basically, determining what to call when you have this:

void foo (int i);
template <typename T> void foo (T t);

is a lot easier than figuring out what to call when you have this:

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

The possibilities for constructors are too immense to be able to sort out through some heuristic like is done for function templates, so the standard simply doesn't even try (it's the right call, in my opinion). Instead, templated types can provide make_**** functions (make_pair comes to mind) which serve as templated constructors.


I think at best you could hope for a declaration such as

TemplatizedType<> bar(new Foo());

but this kind of deduction is not going to happen. I suppose the greatest reason would be that the compiler first needs to know which TemplatizedType to instantiate, before it can even check to see what constructors there are.

With C++0x you will be able to combine make_xxx functions that deduce template arguments with the auto keyword:

auto bar = make_templatized_type(new Foo());
0

精彩评论

暂无评论...
验证码 换一张
取 消