C ++ 03 §14.7.1p1:
Если специализация шаблона класса не была явно создана (14.7.2) или явно специализирована (14.7.3), специализация шаблона класса создается неявно, когда на специализацию ссылаются в контексте, который требует полностью определенного типа объекта или когда полнота типа класса влияет на семантику программы. Неявная реализация специализации шаблона класса вызывает неявную реализацию объявлений, , но не определений или аргументов по умолчанию, функций-членов класса, классов-членов, статических членов-данных и шаблонов элементов; ...
Таким образом, этот код не может создать экземпляр Can_copy :: constraints:
template<class T1, class T2>
struct Can_copy {
static void constraints(T1 a, T2 b) { T2 c = a; b = a; }
Can_copy() { /* note the change here */ }
};
template<class Container>
void draw_all(Container& c) {
typedef typename Container::value_type T;
Can_copy<T,Shape*>(); // accept containers of only Shape*s
}
Но в исходном коде, когда создается экземпляр ctor Can_copy, как и должно быть, когда он используется, его тело (определение) также хорошо, и это вызывает создание экземпляра Can_copy :: constraints.
Вы можете увидеть эту же проблему в обратном порядке, когда явное создание дает вам все, даже то, что вам не нужно:
typedef std::list<int>::iterator Iter;
std::reverse_iterator<Iter> x; // Implicit instantiation; works.
template std::reverse_iterator<Iter>;
// Explicit instantiation; fails to instantiate op+ and other operators used
// for random access iterators from reverse_iterator.