1. Pokud ta funkce copy pracuje tak, že si bere adresu začátku a konce zdrojové kolekce a iterátor cílové kolekce, tak musí být logicky cíl alespoň tak velký jako zdroj, jinak by to rvala mimo alokovanou paměť (proto je podle mě vhodá tak max. na hloupá pole v C, tady bude asi lepší použít standardní kopírující konstruktor vectoru - třeba *smart_vec2 = *smart_vec1)
2. nerozumím otázce
3. tohle by se většínou řešilo raw pointerem - https://en.cppreference.com/w/cpp/memory/shared_ptr/get, nebo lépe referencí.., templatem by to šlo taky