I have a bunch of 开发者_如何学Pythonfunctions which read completely identical except for one line of code, which is different depending on the type of input parameter.
Example:
void Func(std::vector<int> input)
{
DoSomethingGeneral1();
...
DoSomethingSpecialWithStdVector(input);
...
DoSomethingGeneral2();
}
void Func(int input)
{
DoSomethingGeneral1();
...
DoSomethingSpecialWithInt(input);
...
DoSomethingGeneral2();
}
void Func(std::string input)
{
DoSomethingGeneral1();
...
DoSomethingSpecialWithStdString(input);
...
DoSomethingGeneral2();
}
I wonder how I could avoid this duplication using a template-like mechanism. If I understand "specialization" correctly, it does not avoid to have the code of the specialized functions twice?
here you go.. changed the parameters to references to avoid copies + assure you can use the changed values again in Func()
void DoSomethingSpecial( std::vector<int>& input ){}
void DoSomethingSpecial( int& input ){}
void DoSomethingSpecial( std::string& input ){}
template< typename T >
void Func( T input )
{
DoSomethingGeneral1();
DoSomethingSpecial(input);
DoSomethingGeneral2();
}
I believe there is no need for template speciaization, you can use simple function overloading, something like this:
void DoSomethingSpecial(const std::vector<int>& input)
{
}
void DoSomethingSpecial(string s)
{
}
void DoSomethingSpecial(int input)
{
}
template <typename T>
void Func(const T& input)
{
//DoSomethingGeneral1();
DoSomethingSpecial(input);
//DoSomethingGeneral2();
}
int main()
{
std::vector<int> a;
Func(a);
Func("abc");
Func(10);
}
The best way is to make Func
as template:
template<typename T>
void Func(T input);
And overload the DoSomethingSpecial...()
:
void DoSomethingSpecial(std::string);
void DoSomethingSpecial(int);
void DoSomethingSpecial(std::vector<int>);
As a matter of style, you might want to draw out the parts that are different as a trivial template class that is more easily specialized. As an example of this technique, consider your favorite template implementation of an unordered set (or hash_set). Such implementations require you to specialize a simple hash_key< T > template if there isn't a specialization already available. They don't require you to specialize the complete container.
Although your example is simple enough to just specialize the whole function, in general I would implement Func< T > generically and specialize DoSomethingSpecial< T > like so:
template< class T >
void DoSomethingSpecial(T &input)
{
...
}
template< class T >
void Func(T input)
{
DoSomethingGeneral1();
...
DoSomethingSpecial(T);
...
DoSomethingGeneral2();
}
template<>
void DoSomethingSpecial(std::string &input)
{
...
}
template<>
void DoSomethingSpecial(int &input)
{
...
}
Declare a generic version but only define specializations:
template<class T>
void DoSpecificStuff( T& withWhat );
template<>
void DoSpecificStuff( int& withWhat)
{
//implementation
}
template<>
void DoSpecificStuff( std::vector<int>& withWhat)
{
//implementation
}
精彩评论