2009-11-02 1 views
1

Предположим, у меня есть объект, который имеет переменную-член, которая имеет некоторый тип шаблона. Так, в объявлении класса, было бы что-то вроде этого:Почему инициализация типа шаблона требует повторения типа переменной?

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

EDIT (пытается уточнить): По сути, мне кажется, что тип бара (включая параметризованный тип) уже указан в его объявлении как член класса и, следовательно, не требует повторения при инициализации.

Если это не имеет смысла, дайте мне знать (я обнаружил это в основном посредством проб и ошибок и некоторых полезных людей в IRC, поэтому, если мое понимание того, что происходит здесь, является неправильным, помощь в этом также будет с благодарностью.)

+0

Is «бар» переменная член класса или в каком контексте делать вам объявлять и использовать бар? –

+1

Это определенно неправильно - вам не нужно повторять объявление переменной. Вставьте полный образец. –

+0

Вы хотите сказать, что 'TemplatizedType ' имеет конструктор, который принимает 'T *' в качестве аргумента, и вы хотите, чтобы 'T' выводился из параметра для перехода к конструктору? –

ответ

2
templatizedType<Foo> bar; 

вызывает конструктор по умолчанию, в то время как

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

вызывает конструктор, принимающий Foo * в качестве первого аргумента чтобы построить объект, вы должны написать этот тип. Вот почему,

bar(new Foo()) 

не вызывает конструктор templatizedType, но вместо этого вызывает метод уже построенного объекта этого типа. Этот метод может быть, например:

void operator()(Foo*) 

надеюсь, что это помогает ..

1

Поскольку C++ является строго типизированным языком, он хочет, чтобы убедиться, что это «бар», что вы имеете в виду на самом деле что-то что может принять «новый Foo()» поэтому вы должны дать ему тип, как и в строке:

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

Кроме того, если вы только что сказали

bar(new Foo()); 

Кто скажет, что это не панель функций() против объявления переменной?

0

Вы уверены, что вы не просто перегружать имя bar в качестве локальной переменной в конструкторе, т.е. если ваш класс называется A вы делаете

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

вместо

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

Причина в том, что решение перегрузок для шаблонных функций уже сложно, без необходимости иметь дело с гадостью, которая является частичной специализацией и шаблонами членов шаблонов (я знаю, это звучит запутанно. Это потому, смущает.)

В принципе, определение, как назвать, когда у вас есть это:

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), которые служат в качестве шаблонных конструкторов.

0

Я думаю, что в лучшем случае можно было надеяться на заявления, такие как

TemplatizedType<> bar(new Foo()); 

, но этот вид вычета не будет. Я полагаю, что самая большая причина заключалась в том, что компилятор сначала должен знать, какой TemplatizedType должен создать экземпляр, прежде чем он сможет даже проверить, какие конструкторы существуют.

В C++ 0x вы сможете объединить make_xxx функции, которые выводят аргументы шаблона с авто ключевое слово:

auto bar = make_templatized_type(new Foo()); 
Смежные вопросы