开发者

Templates for code which is similar but not identical?

开发者 https://www.devze.com 2023-03-11 11:53 出处:网络
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.

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
}
0

精彩评论

暂无评论...
验证码 换一张
取 消