One good feature of C++ compilers is automatic implicit type deduction for template functions, i.e. retrieving template argument types from the passed formal parameters.
template <typename T>
void do_something(T arg)
{
std::cout<<arg<<std::endl;
}
...
do_something(1); // T = int
do_something(1.0); // T = double
Though this feature is not supported for classes, and this is logical, as we can have various versions of constructors, and if we create some objects of the class without explicitly specifying the template type the type could not be deduced correctly, e.g.:
template <typename T>
class Container
{
public:
Container(const T& elem, int cnt = 1); // creates container
// with 'cnt' copies of 'elem'
Container(int cnt); // creates a container with one T() element
Container(const Container<T>& other); // copy constructor
...
};
...
int a = 5;
Container c(a); // which constructor to call : first or second ???
To avoid every time specifying the concrete types for templates, we can create a helper function, making use of implicit type deduction of function template arguments. So now we can write
template <typename T>
Container<T> make_container(const T& elem)
{
return Container<T>(elem);
}
Now we can call make_container without worrying about the type, just passing the object to be kept in container. But this would be useful only we need to pass an object to another function, otherwise we should specify the concrete type to declare an object of class Container<T>. This technique is much used in STL and boost libraries (e.g. std::make_pair in <utility>). It can be helpful if your type T is some complex expression, for instance a pointer to template function taking as arguments several objects of other complex types etc.
template <typename T>
void do_something(T arg)
{
std::cout<<arg<<std::endl;
}
...
do_something(1); // T = int
do_something(1.0); // T = double
Though this feature is not supported for classes, and this is logical, as we can have various versions of constructors, and if we create some objects of the class without explicitly specifying the template type the type could not be deduced correctly, e.g.:
template <typename T>
class Container
{
public:
Container(const T& elem, int cnt = 1); // creates container
// with 'cnt' copies of 'elem'
Container(int cnt); // creates a container with one T() element
Container(const Container<T>& other); // copy constructor
...
};
...
int a = 5;
Container c(a); // which constructor to call : first or second ???
To avoid every time specifying the concrete types for templates, we can create a helper function, making use of implicit type deduction of function template arguments. So now we can write
template <typename T>
Container<T> make_container(const T& elem)
{
return Container<T>(elem);
}
Now we can call make_container without worrying about the type, just passing the object to be kept in container. But this would be useful only we need to pass an object to another function, otherwise we should specify the concrete type to declare an object of class Container<T>. This technique is much used in STL and boost libraries (e.g. std::make_pair in <utility>). It can be helpful if your type T is some complex expression, for instance a pointer to template function taking as arguments several objects of other complex types etc.
No comments:
Post a Comment