Эти две связаны только так же, как здесь связаны две свободные функции foo
:
void foo() {};
template <typename T>
void foo() {}
Будучи членами класса шаблона, оба экземпляра будут создаваться по запросу для неявных экземпляров. С другой стороны, если вы явно создаете экземпляр класса шаблона, нешаблонная функция будет сгенерирована компилятором, а функция-член шаблона — нет.
Помимо этого, обычные предостережения: шаблонные функции будут соответствовать только точным типам, в то время как нешаблонные функции допускают неявные преобразования:
template <typename T>
struct tmpl {
void foo( T, T ) {}
template <typename U>
void bar( U, U ) {}
};
tmpl<int> t;
t.foo( 5, 1. ); // fine, will convert 1. from double to int
t.bar( 5, 1. ); // error
И все остальные различия между шаблонными и не шаблонными функциями.
Чего я действительно не понимаю, так это почему это вас так сбивает с толку. Кажется, что вы рассматриваете экземпляр как единственное свойство функций, которым оно не является. Что вас действительно беспокоит? Как вы думаете, почему шаблон и нешаблонные функции будут одинаковы?
В частности, я чувствую, что вы тратите слишком много усилий на детали реализации. В большинстве случаев создание экземпляра одной или всех функций-членов класса-шаблона на самом деле не влияет на семантику вашей программы. Если вашей программе нужна функция-член, компилятор сгенерирует для нее код, если ваша программа не нуждается в этом, нет никакой разницы, сгенерировала она код или нет (учитывайте, что компоновщик может удалить любой символ, в чем разница между тем, что функция-член никогда не была сгенерирована или она была удалена компоновщиком?)
person
David Rodríguez - dribeas
schedule
30.06.2012