I’m trying to write a class-template where the method signatures change depending on the template parameters. My goal is to have as little code duplication as possible. Consider this example, first the class declaration:
// a.hxx
#ifndef A_HXX
#define A_HXX
template<typename T>
struct A
{
void foo(T value) const;
void bar() const;
};
#include <string>
#ifndef short_declaration
template<>
struct A<std::string>
{
void foo(const std::string &value) const;
void bar() const;
};
#else // short_declaration
template<>
struct A<std::string>
{
void foo(const std::string &value) const;
};
#endif // short_declaration
#endif // A_HXX
Now the class definition:
// a_impl.hxx
#ifndef A_IMPL_HXX
#define A_IMPL_HXX
#include "a.hxx"
#include <iostream>
#include <typeinfo>
template<typename T>
void A<T>::foo(T value) const
{
std::cout << "A<T=" << typeid(T).name() << ">::foo(" << value << ")"
<< std::endl;
}
template<typename T>
void A<T>::bar() const
{
std::cout << "A<T=" << typeid(T).name() << ">::bar()" << std::endl;
}
void A<std::string>::foo(const std::string &value) const
{
std::cout << "A<std::string>::foo(" << value << ")" << std::endl;
}
#ifndef skip_duplicates
void A<std::string>::bar() const
{
std::cout << "A<std::string>::bar()" << std::endl;
}
#endif // skip_duplicates
#endif // A_IMPL_HXX
And now a test program:
// test.cxx
//#define skip_duplicates
//#define short_declaration
#include "a_impl.hxx"
int main(void)
{
A<int> obj1;
A<std::string> obj2;
int value1(1);
std::string value2("baz");
obj1.foo(value1);
obj1.bar();
obj2.foo(value2);
obj2.bar();
return 0;
}
If compiled like this, I get the expected output of (for my implementation of typeid):
A<T=i>::foo(1)
A<T=i>::bar()
A<std::string>::foo(baz)
A<std::string>::bar()
But I would of course like a way to enable either skip_duplicates or even short_declaration in my example. To a somewhat similar question, ecatmur replied that the full class needs to be given, so at least defining short_declaration would not work.
How do others handle the problem of creating class templates with methods that may take large objects as arguments?
Based on the answer by hansmaad and the comment by Yakk, I think the following is the solution I will go with:
And this implementation:
The test program can remain as is or get additional lines like these:
Thank you both for answering and for your suggestions!