Почему инициализация типа шаблона требует повторения типа переменной? - PullRequest
1 голос
/ 02 ноября 2009

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

// 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 ]

2 голосов
/ 02 ноября 2009
templatizedType<Foo> bar;

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

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

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

bar( new Foo() )

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

void operator()( Foo* )

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

1 голос
/ 02 ноября 2009

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

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

Также, если вы просто скажете

bar(new Foo());

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

0 голосов
/ 03 ноября 2009

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

TemplatizedType<> bar(new Foo());

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

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

auto bar = make_templatized_type(new Foo());
0 голосов
/ 03 ноября 2009

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

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

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 голосов
/ 02 ноября 2009

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

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

вместо

A::A()
    : bar(new Foo())
{
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...