Следует отметить, что это работает, потому что ваш шаблонный класс принимает объект по значению:
template<typename T>
void func(T type) // this takes a T by value
...
из-за этого он может принимать либо lvalue (например, действительную переменную), либо rvalue (например, временную).
Если по какой-то причине вы хотите ограничить func
только взятием lvalue, вы можете изменить функцию для использования передачи по ссылке:
template <typename T>
void func(T &type) // this takes a T by reference
...
Использование передачи по ссылке позволяет побочному эффекту функции изменять объект.