C++: Inheritance v. Containment for a templatized class - c++

I have the following struct:
template <typename T>
struct Odp
{
T m_t;
};
I want to specialize it so I can add an operator so the type plays nicely with STL sets. (I can't modify Odp directly; it's legacy code.) Here are two methods I see of doing it:
struct Ftw : public Odp<int>
{
bool operator==(const Ftw& rhs)
{
return m_t == rhs.m_t;
}
};
struct FtwContain
{
Odp<int> odp;
bool operator==(const FtwContain& rhs)
{
return odp.m_t == rhs.odp.m_t;
}
};
Is there any reason to prefer the second over the first? The first method appears to allow cleaner code:
Ftw ftw;
ftw.m_t = 2;
FtwContain ftwContain;
ftwContain.odp.m_t = 2;
(Also, there's a chance that I'm confused about what the term "template specialization" means.)

I don't believe there is any need to create a new type - simply write a free function:
template <typename T>
bool operator==( const Odp<T> & a, const Odp <T> & b ) {
return a.m_t == b.m_t;
}

You may indeed be confused about the terminilogy. (Partial) template specialization normally referes to a specific implementation of a templated class /struct for a dedicated type. I.e. you may have a generic template class Hash that provides hash values for types using a method getHash. This method then has a generic implementation, that doesn't care about the type, and maybe a special implementation for hash values on strings:
// default implementation
template<typename T> class Hash { int getHash(T val) { return val; } }
// string implementation
template<> class Hash<std::string> { int getHash(std::string val) { return val[0] || val[1]; } }
What you are doing in ur examples however is not template specialization but inheritance (in the first approach) and using the Odp template as a client. In both cases, if anyone uses the Odp template as in Odp<int> odp, the original implementation will be used, which may not be what you want. If you would use proper template specialization, Odp<int> would refer to your specialized code.

Why not deriving Odp to MyOdp, put your (generic) code in it and just make Ftw derive from Odp (as in your first example) or using a typedef ?
By the way that not specialization but instanciation. Template specialization is when you (re)define a method for a specific type.

I usually prefer composition over inheritance, but it really depends on the design. Is Ftw a type of Odp or does Ftw contain an Odp.
I wouldn't choose the method based on cleaner code (since it's not that much of a difference), I would choose the method based on conceptually what is the relationship between Odp and Ftw.

In the case you mentioned, I think a free function is possibly the cleanest way with the least amount of rebuild issues. Put this free function in a separate cpp file and you should be good to go.
Possible cases for derivation
You would want to derive if you have to pass your object to some function which takes a base-class type
Is the derived class a type of the first type. If so, yes (eg., a carnivore is an animal)
3.If there are protected methods in the base class that you want to use in your derived class. I am not sure if the structure you mentioned is the complete code or only the relevant section. If it is not, then this might be one reason you want to derive.
Possible cases for containing
You merely want to use the class and there is no is-a relationship. TBH, one can simulate an is-a with containing objects too, where in the container type acts like a proxy for the contained-type (I think this is a design pattern, but am not sure of the name of the pattern).
You are interested in using only one or two methods, and there is no worry of a shared state
This object is never passed to any other interface which requires a base class (one can always pass the contained object, but that looks dirty. Also, toss in virtual functions and things are different. Sorry, I digress).

As Neil mentions, operator== can well be a free function.
Another option: standard library allows the use of custom predicate objects. In this case:
#include <set>
template <typename T>
struct Odp
{
T m_t;
};
struct CompareOdp
{
template <class T>
bool operator() (const Odp<T>& a, const Odp<T>& b) const
{
return a.m_t < b.m_t;
}
};
int main()
{
std::set<Odp<int>, CompareOdp > my_set;
Odp<int> value = {10};
my_set.find(value);
}
(Not sure, whether it might be a better idea to make the whole predicate a template. Making just operator() a template seems to make it easier to use, as it leaves more things to the compiler to figure out. Not sure if it could back-fire in some scenarios.)
Also note that std::set uses a predicate for ordering (by default std::less<X>), not for equality tests.

Related

Fully specialized class as template function parameter

I have written two different container classes, which have the same interface but use different member data and algorithms to operate on their members. I also have a template function that takes a container and does some useful calculation:
class Container1
{
// implementation here
};
class Container2
{
// implementation here
};
template<typename ContainerType>
void my_function(ContainerType const& container, /* other parameters */)
{
// ...
}
What bothers me is the fact that 'my_function' should only accept Container1 or Container2, but this is not expressed by the code, since ContainerType can be any type. The function is templated by container type since it does the same thing no matter what is the internal implemetation of container.
I am considering a variant where Container1 and Container2 would be full specializations of a template class. Then I could be more specific about the argument of my_function:
template<typename T>
class Container;
// Tags to mark different container types
struct ContainerType1 { };
struct ContainerType2 { };
template<>
class Container<ContainerType1>
{
// implementation
};
template<>
class Container<ContainerType2>
{
// implementation
};
template<typename T>
void my_function(Container<T> const& container, /* other parameters */)
{
}
In the first case, the compilation with a wrong template parameter will fail if 'ContainerType' does not have the interface required by my_function, which is not very informative. In the second case, I would also get a compiler error (failed template parameter deduction) if I supply anything else than Container<ContainerType1> or Container<ContainerType2>, but I like it better since it provides a hint about what kind of template parameter is expected.
What are you thoughts about this? Is it a good design idea or not? Do you think it is worth the change in the code? There are many other functions like my_function in the code and sometimes it is not obvious what kind of template parameters they expect. What are my other options to make my_function more specific? I am aware the existence of Boost Concept Check Library.
For the sake of argument, let's suppose that I don't want to solve the problem by using inheritance and virtual functions.
In case it is relevant to the discussion, the common interface of Container1 and Container2 is imposed by using CRTP. There might be more container classes in the future.
There are a few solutions to this kind of problem.
Your solution (implementing your types as a template specialization) is one, but one I don't particularly like.
Another is the CRTP:
template<typename T>
struct Container {
// optional, but I find it helpeful
T* self() { return static_cast<T*>(this); }
T const* self() const { return static_cast<T const*>(this); }
// common code between every implementation goes here. It accesses itself through self(), never this
};
class ContainerType1: public Container<ContainerType1> {
// more details
};
class ContainerType2: public Container<ContainerType2> {
// more details
};
that is the core of the CRTP.
Then:
template<typename T>
void my_function(Container<T> const& container_, /* other parameters */)
{
T const& container = *(container.self());
}
and bob is your uncle. As a bonus, this provides a place to put common code.
Another option is a tag traits class that marks the types you want to support, like iterator_traits.
template<typename T>
struct is_container : std::false_type {};
template<>
struct is_container<ContainerType1> : std::true_type {};
template<>
struct is_container<ContainerType2> : std::true_type {};
you can even do SFINAE style pattern matching to detect a base type (like how iterators work).
Now your method can test on is_container<T>::value, or do tag dispatching on is_container<T>{}.
I think your first version is do-able.
At the end of the day, you always have to choose the optimum approach. Second one may look like an overkill although it gets the point across.
If you Container classes will both have a common function (let's say Container1::hasPackage() or Container2::hasPackage() and you choose to call it within my_function then it straight away puts your point across that the eligibility to call it is that function itself. After going through many such projects you will start reading the templates in a reverse manner - starting from the template definition - to see what least properties are needed qualify a particular class.
Having said all this, perhaps your question was more suited for Code Review
One example I created on ideone was using your classes but adding a member variable name to them both which is expected by my_function. Of course there may be classes that will support name but the developer may also burn his fingers a few times to realize the idea behind the function.

Template class with no use of template argument

I have stumbled many times on classes defined like
class PureVirtualClass
{
virtual int foo() = 0;
virtual bool bar() = 0;
}
template <class T> class ImplClass : public virtual PureVirtualClass
{
virtual ~ImplClass(){};
int foo() { return 42;}
bool bar() { return true;}
//several other method having nothing to do with T
}
This "design" appears so often I want to think the original developer knew what he was doing by defining ImplClass as template class but without any reference to the template argument T anywhere. My own c++ template knowledge is kinda limited.
Is there a benefit to this or is it just a confused programmer?
There can be a benefit for classes being templated but not depending on the argument. Most often you see such things to define (empty) tag-structures for template metaprogramming:
template <class X>
struct some_tag {};
The benefit of classes like yours in general is that while you have the same functionality in each class, they are different classes and you can't copy one into the other, i.e. an object of type ImplClass<int> is not compatible with another object of type ImplCalss<float>.
There are many useful cases of the idea mentioned by Arne. For instance, looking at Very basic tuple implementation, this is how a single tuple element is defined:
template <size_t N, typename T>
class TupleElem
{
T elem;
public:
T& get() { return elem; }
const T& get() const { return elem; }
};
It is templated on N, without depending on it. Why? Because the tuple implementation
template <size_t... N, typename... T>
class TupleImpl <sizes <N...>, T...> : TupleElem <N, T>...
{
//..
};
derives multiple such elements, each with a unique N, serving as an identifier. Without it, TupleImpl would be deriving the same class twice, had two element types been identical within parameter pack T.... Neither random access to elements would work in this case (via an explicit call of function get() of the appropriate TupleElem base class, which would be ambiguous), nor empty base optimization (via specializing TupleElem for empty types T to not have a data member of type T).
This is a real use case, and exactly how std::tuple is implemented by clang. Of course, a class like TupleElem would be a hidden implementation detail, and not part of the interface. For instance, gcc follows an entirely different recursive class design.
In general, you will need to study the context where classes are used to understand the intent of the designer.
maybe that developer simply is too lazy to split the classes into .h and .cpp files?
Without using templates, linker errors would occur if the classes are used in multiple compilations units. When using templates, the linker usually discards duplicate instantiations of a template at link time (or handles the problem in a different way).
While this may be an answer to "why did the developer do this", I would not recommend this if the question was "when should I introduce template arguments which are never used" (see the other answers for this). Even though it is annoying to split code into .h and .cpp (especially when used to languages like Java or C#), it's the usual C++ way. And it is definitely easier to read/understand than using templates only for this purpose. Also, it makes the use of the classes less readable.

Call function of template class created at runtime

I have a tricky question about C++(11) template classes and their instantiation with types determined at runtime:
Following scenario:
The user defines the type of a template class using a config file (ROS parameters). This determines only the type of the template class, not the further logic:
Class definition:
template<typename T>
class MyClass {
//[...]
}
Exemplary code:
/* [Read parameter and write result to bool use_int] */
std::unique_ptr<MyClass> myclassptr {nullptr};
if(use_int) {
myclassptr.reset(MyClass<int>);
} else {
myclassptr.reset(MyClass<double>);
}
myclassptr->foobar();
/* [more code making use of myclassptr] */
So this code is (of course) not compiling, because the unique_ptr template must be specified also with the template type. However, then the problem arises that the template type must be the same for all objects assigned using reset.
One ugly solution would be to copy the code myclassptr->foobar(); and the following into each branch of if/else, which I really don't like.
I would like to see a solution similar to this:
/* [Read parameter and write result to bool use_int] */
MyClass<use_int ? int : double> myclass;
myclass.foobar();
What I have read so far is that something like this is also not possible.
Does anybody have a nice solution for this?
The simplest way to do this is:
class IClass{
virtual ~IClass {}
virtual void foobar()=0;
};
template<typename T>
class MyClass:public IClass {
public:
void foobar() override {
// code here
}
};
std::unique_ptr<IClass> myclassptr {};
if(use_int) {
myclassptr.reset(new MyClass<int>());
} else {
myclassptr.reset(new MyClass<double>());
}
myclassptr->foobar();
boost::variant would be another solution, but is usually used for unrelated types. Type erasure could be done, but again that is usually done when you have unrelated types you want to impose a uniform interface on.
In other languages generics look sort of like templates, but are actually an abstract interface with auto-generated typecasting and some typechecking added. C++ templates are function or class compile time factories. Two outputs of such factories are unrelated at runtime by default, and you can add such relations if you want.
Depending on what you want, you can make MyClass a variant type that holds either an int or a double, or you could use type erasure to hide the implementation behind an interface. The Boost.Variant library can help to implement the former.

Should I prefer mixins or function templates to add behavior to a set of unrelated types?

Mixins and function templates are two different ways of providing a behavior to a wide set of types, as long as these types meet some requirements.
For example, let's assume that I want to write some code that allows me to save an object to a file, as long as this object provides a toString member function (this is a rather silly example, but bear with me). A first solution is to write a function template like the following:
template <typename T>
void toFile(T const & obj, std::string const & filename)
{
std::ofstream file(filename);
file << obj.toString() << '\n';
}
...
SomeClass o1;
toFile(o1, "foo.txt");
SomeOtherType o2;
toFile(o2, "bar.txt");
Another solution is to use a mixin, using CRTP:
template <typename Derived>
struct ToFile
{
void toFile(std::string const & filename) const
{
Derived * that = static_cast<Derived const *>(this);
std::ofstream file(filename);
file << that->toString() << '\n';
}
};
struct SomeClass : public ToFile<SomeClass>
{
void toString() const {...}
};
...
SomeClass o1;
o.toFile("foo.txt");
SomeOtherType o2;
o2.toFile("bar.txt");
What are the pros and cons of these two approaches? Is there a favored one, and if so, why?
The first approach is much more flexible, as it can be made to work with any type that provides any way to be converted to a std::string (this can be achieved using traits-classes) without the need to modify that type. Your second approach would always require modification of a type in order to add functionality.
Pro function templates: the coupling is looser. You don't need to derive from anything to get the functionality in a new class; in your example, you only implement the toString method and that's it. You can even use a limited form of duck typing, since the type of toString isn't specified.
Pro mixins: nothing, strictly; your requirement is for something that works with unrelated classes and mixins cause them to be become related.
Edit: Alright, due to the way the C++ type system works, the mixin solution will strictly produce unrelated classes. I'd go with the template function solution, though.
I would like to propose an alternative, often forgotten because it is a mix of duck-typing and interfaces, and very few languages propose this feat (note: very close to Go's take to interfaces actually).
// 1. Ask for a free function to exist:
void toString(std::string& buffer, SomeClass const& sc);
// 2. Create an interface that exposes this function
class ToString {
public:
virtual ~ToString() {}
virtual void toString(std::string& buffer) const = 0;
}; // class ToString
// 3. Create an adapter class (bit of magic)
template <typename T>
class ToStringT final: public ToString {
public:
ToStringT(T const& t): t(t) {}
virtual void toString(std::string& buffer) const override {
toString(buffer, t);
}
private:
T t; // note: for reference you need a reference wrapper
// I won't delve into this right now, suffice to say
// it's feasible and only require one template overload
// of toString.
}; // class ToStringT
// 4. Create an adapter maker
template <typename T>
ToStringT<T> toString(T const& t) { return std::move(ToStringT<T>(t)); }
And now ? Enjoy!
void print(ToString const& ts); // aka: the most important const
int main() {
SomeClass sc;
print(toString(sc));
};
The two stages is a bit heavyweight, however it gives an astonishing degree of functionality:
No hard-wiring data / interface (thanks to duck-typing)
Low-coupling (thanks to abstract classes)
And also easy integration:
You can write an "adapter" for an already existing interface, and migrate from an OO code base to a more agile one
You can write an "interface" for an already existing set of overloads, and migrate from a Generic code base to a more clustered one
Apart from the amount of boiler-plate, it's really amazing how you seamlessly pick advantages from both worlds.
A few thoughts I had while writing this question:
Arguments in favor of template functions:
A function can be overloaded, so third-party and built-in types can be handled.
Arguments in favor of mixins:
Homogeneous syntax: the added behavior is invoked like any other member functions. However, it is well known that the interface of a C++ class includes not only its public member functions but also the free functions that operates on instances of this type, so this is just an aesthetic improvement.
By adding a non-template base class to the mixins, we obtain an interface (in the Java/C# sense) that can be use to handle all objects providing the behavior. For example, if we make ToFile<T> inherits from FileWritable (declaring a pure virtual toFile member function), we can have a collection of FileWritable without having to resort to complicated heterogeneous data structures.
Regarding usage, I'd say that function templates are more idiomatic in C++.

Advantages of an empty class in C++

What could be the possible advantages/uses of having an empty class?
P.S:
This question might sound trivial to some of you but it is just for learning purpose and has no practical significance. FYI googling didn't help.
One use would be in template (meta-)programming: for instance, iterator tags are implemented as empty classes. The only purpose here is to pass around information at compilation time so you can check, if an iterator passed to e.g. a template function meets specific requirements.
EXAMPLE:
This is really simplified, just to ge an idea. Here the purpose of the tag class is to decide, which implementation of an algorithm to use:
class forward_iterator_tag {};
class random_access_iterator_tag {};
class MySimpleForwardIterator {
public:
typedef typename forward_iterator_tag tag;
// ...
};
class MySimpleRandomIterator {
public:
typedef typename random_access_iterator_tag tag;
// ...
};
template<class iterator, class tag>
void myfunc_int(iterator it, tag t) {
// general implementation of myfunc
}
template<class iterator>
void myfunc_int<iterator, forward_iterator_tag>(iterator it) {
// Implementation for forward iterators
}
template<class iterator>
void myfunc_int<iterator, random_access_iterator_tag>(iterator it) {
// Implementation for random access iterators
}
template<class iterator>
void myfunc(iterator it) {
myfunc_int<iterator, typename iterator::tag>(it);
}
(I hope I got this right, it's been a while since I used this ...)
With this code, you can call myfunc on an arbitrary iterator, and let the compiler choose the correct implementation depending on the iterator type (i.e. tag).
The following can be used to have a boost::variant which can hold an (SQL) NULL value for example.
class Null { };
typedef boost::variant<Null, std::string, int> Value;
To make it more useful things like operator== and operator<< are handy. For example:
std::ostream& operator<<(std::ostream &lhs, const Null &rhs)
{
lhs << "*NULL*";
return lhs;
}
int main()
{
Variant v("hello");
std::cout << v << std::endl;
v = Null();
std::cout << v << std::endl;
...
}
Will give:
hello
*NULL*
In the STL, Standard Template Library of the C++, for example you have
template<class _Arg,
class _Result>
struct unary_function
{ // base class for unary functions
typedef _Arg argument_type;
typedef _Result result_type;
};
When defining a functor, you can inherit unary_function, and then you have the typedef defined automatically at your disposal.
An empty class could be used as a "token" defining something unique; in certain patterns, you want an implementation-agnostic representation of a unique instance, which has no value to the developer other than its uniqueness. One example is Unit of Work; you may not care one bit about what's going on inside your performer, but you want to tell that performer that the tasks you're telling it to perform are part of an atomic set. An empty class representing the Unit of Work to the outside world may be perfect in this case; almost anything a Unit of Work object could store or do (encapsulating a DB transaction, exposing Commit/Rollback behaviors) would start tying you to a particular implementation, but an object reference is useful to provide a unique but copyable and passable reference to the atomic set of tasks.
You can use it like a placeholder for checking purpose or as enabler to special functionality. For example in Java exist the "empty" interface Serializable used to specify if a class is serializable.
"empty" classes means classes which have no data members?
They typically declare typedefs or member functions, and you can extend them with your own classes.
Here is an interesting link with answers to why its allowed. You might find this helpful to find situations where it might be useful.
As others have said, often an empty class (or struct) is used a placeholder, a differentiator, a token, etc.
For example, a lot of people are unaware that there are "nothrow" versions of operator new. The syntax to invoke nothrow new is:
p = new(std::nothrow) Bar;
and std::nothrow is defined simply as
struct nothrow_t {}; //defined in namespace std
The answer by MartinStettner is fine though just to highlight an important point here: The concept of iterator tags or for that matter any tags in C++, is not strictly dependent on empty classes. The C++ tags, if stl writers would have wanted to, could well have been non-empty classes; that should work but then it won't add any additional value; at least for compile time acrobatics that it is usually reserved for.
For the sake of typeid
Suppose we have comparable interface Id. We need fill some container with unique instances of this interface. How to guarantee the uniqueness of Id instances produced by independent software parts? «Independent parts» means some different dynamic libraries, compiled by different programmers from different locations
One of decisions is to compare typeid of some type first. If typeid matches, convert and compare other implementation specific properties. C++ language guarantees uniqueness of any type within process memory. Which type should be used for this purpose? Any type with minimum resource consumption — empty one