C++ template method, changing the behavior based on the template class
I'm trying to write a c++ template method. Below is a sample code demonstrating what I want to do within the method.
template<class T>
void method(T value) {
// This string should change based on type T
char *str = "Int" or "Float" or .. ;
...
...
std::cout << value << " is of type " << str << std::cout;
}
Basically, the behavior (the string value in this example) of the method will cha开发者_JAVA百科nge based on the type T. How could I do this with template?
You can specialize your template over different types. If you start with a base case:
template <class T>
void method(T value);
You can then declare different behavior for any specific value of T
:
template <>
void method<int>(int value) {
// special behavior
}
And so forth. But since only the input type of your function is changing, you really don't need templates in this case! You can just overload your function with different argument types:
void method(int T);
void method(float T);
void method(void* T);
EDIT: Using template specialization to get the name of a type and use it in another function template:
template <class T>
std::string type_to_string();
template <>
std::string type_to_string<int>() {
return "int";
}
template <>
std::string type_to_string<float>() {
return "float";
}
template <class T>
some_other_function(T value) {
std::cout << value << " is a " << type_to_string<T>() << std::endl;
}
Of course, you can still do this without templates:
std::string type_to_string(int) {
return "int";
}
some_other_function(int value) {
std::cout << value << " is a " << type_to_string(value) << std::endl;
}
If you had to do some complex type-level computation, I'd suggest using templates. But here, I think you can accomplish what you want rather nicely without them. Either way, the idiomatic way (with or without templates) is to split your function into its different natural pieces.
Off the top of my head a couple of ways:
- Perhaps T could have a method that returns the appropriate string, and all your T's provide that method.
Then you can say:
char *str = T.getTheAppropriateString();
- RTTI and dynamic_cast. See http://en.wikipedia.org/wiki/Run-time_type_information.
It depends on how much and how often the behavior changes. If the behavior is different for each type, you might consider not using a template at all, just standard overloading. If the behavior is usually the same, but completely different for one or two cases, you can use explicit specialization for these cases. If most of the behavior is always the same, but there is one small part that varies, you can either factor that part out into an overloaded function, or use a traits class:
template <typename T> CustomBehavior;
template <typename T>
void
function( T value )
{
// ...
CustomBehavior<T>::specialized(...);
// ...
}
精彩评论