2016-04-04 2 views
3
template <typename T> 
void func(){ 
    T* t = new T(); 
    t->do_something(); 
    ... 
} 

В этом случае, как компилятор знает, что имя типа T будет иметь определенный на нем метод do_something()? В Java мы можем указать, какой интерфейс расширяет общий класс, но C++, по-видимому, не имеет того же синтаксиса. Итак, что получится, если мы позвоним func<AClassThatDoesntHaveDoSomethingDefined>()?Как C++ знает, какие методы поддерживает класс шаблонов при компиляции?

+0

Возможные дубликаты: http://stackoverflow.com/q/122316/365102, http://stackoverflow.com/a/15671344/365102 –

+0

@MateenUlhaq Нет. Я не спрашиваю, как добавить ограничения на шаблоны. Мне более любопытно, почему C++ позволяет компилировать такой код и как он обрабатывает случай, когда вызываемая функция не определена. – OneZero

+1

@OneZero Правилами языка являются то, что до момента создания шаблона выполняется очень мало проверок. Как только шаблон создается, хотя - есть достаточно информации, чтобы знать, что есть проблема, нет? –

ответ

7

Компилятор не знает, пока вы не создадите экземпляр функции шаблона ... с помощью T. Тогда он будет искать, есть ли у T такие методы ... Если нет, вы получите сообщение об ошибке.

Подумайте о типах шаблонов, таких как заполнители, для функции шаблона нет кода, пока он не будет создан с типом. Поэтому, если у вас есть такая функция и ее никогда не вызывается, though it will still undergo some syntax conformance checks by the compiler, она не будет частью сборки. Это одна из многих особенностей templates.

Когда вы звоните func<AClassThatDoesntHaveDoSomethingDefined>(), компилятор заменяет typename T на AClassThatDoesntHaveDoSomethingDefined. И он будет пытаться создать функцию, как это:

void func(){ 
    AClassThatDoesntHaveDoSomethingDefined* t = new AClassThatDoesntHaveDoSomethingDefined(); 
    t->do_something(); 
    ... 
} 

обычных правил для компиляции следует ... если do_something() не определен, вы получите сообщение об ошибке.

Там немного больше информации о шаблонах здесь: https://isocpp.org/wiki/faq/templates

+0

@CaptainGiraffe ... Спасибо. Ответ Модифицированный ... Надеюсь, теперь его лучше ;-) – WhiZTiM

1

Шаблоны не знают Nuthin', пока они не используются. Как только они используются, шаблон превращается в код с аргументами шаблона, замененными для держателей мест. Затем этот сгенерированный код компилируется, и если какой-либо из этих замещаемых аргументов не соответствует требованиям этого вновь созданного кода, вы получите сообщение об ошибке.

Подумайте об этом поэтапно.

Вы определяете следующий шаблон

template<T> 
bool func(T val) 
{ 
    return val.getstate(); 
} 

Во время компиляции,

std::string test; 
if (func(test)) 

найден и запускает шаблон. Затем компилятор выключается и создает

bool func(std::string val) 
{ 
    return val.getstate(); 
} 

из шаблона. Некоторое время спустя во время компиляции эта сгенерированная функция будет скомпилирована и найти std::string::getstate не существует, создавая сообщение об ошибке.

Смежные вопросы