I have written a template class that should expose its template parameter, but I am unsure of the appropriate naming.
I have found three different names for essentially the same thing (as far as I can tell):
std::vector
use value_type
std::unique_ptr
use element_type
std::reference_wrapper
uses just type
What is the idea behind these different names? What standard algorithms or trait classes depend on which name? Which name should I use for my class (something in between a smart pointer and reference wrapper)?
value_type
is a member type of containers (and iterators and such). It provides the type of an object, usually a complete object, which you can create or observe. There is no casting between value_type
-covariant templates.
element_type
is a member type of smart pointers. It provides the type of an observed object. Often smart pointers manage complete objects, but they can also be cast to base subobjects.
type
is a member type of metafunctions. Usually it doesn't describe any particular object.
value_type
is a part of a big family of things to define when you define containers:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef long size_type;
typedef size_type difference_type;
These, in addition to iterators typedef
s, are all used by STL algorithms to deal with your container in an agnostic way, without knowing the type of your container. These are the reason why the same algorithm works on std::vector
, std::deque
and all other STL containers.
On the other hand, std::unique_ptr
and std::reference_wrapper
have their typedefs for completeness and to make it also possible to the developer to deduce types. For example, consider the situation:
typedef std::vectory<double> MyGreatArray;
//Do stuff with MyGreatArray
//What is the type inside MyGreatArray? I want to assign a single element
MyGreatArray::value_type one_element; //now one_element is a double!
MyGreatArray::iterator MyGreatArrayIt; //now this is an iterator vector<double>
one_element = 1.0;
MyGreatArrayIt = MyGreatArray.begin();
(PS: Of course you can use auto
, but this is the case even before C++11)
So you see, you will always have a reference to the type inside the container. It doesn't matter whether it's an STL container or std::unique_ptr
, it's just good practice to have a reference of your template type inside your template class, no matter what it's. Since STL and the C++ standard aims toward generality, you'll always find a reference of your template types inside the classes. This will make it easier for everything you do to be independent of the types you put in your templates.
EDIT:
"Why they have different names?" A: Simply to avoid ambiguity. Consider an algorithm that should take a container and requires only a value_type
. When the names are different, you add extra protection against catastrophic run-time errors. Remember that everything is becoming type-agnostic. The last thing we want is another source of errors by having everything called value_type
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With