I want to define a set of template functions that I can later add to another class in order to provide a subset of functions that can act on a certain type.
For example, this is a generic functor that calls size()
:
// provides the `size()` operation
template<class T>
struct size_op_t
{
auto size() const noexcept
{
// we know that some class is inheriting from us here and that it will have
// a data member called "value_"
return value_.size(); // ERROR: there is no "value_" in size_op_t
}
};
The issue is that there is no value_
data member in size_op_t
. Therefore, compilation fails. However, I know that size_op_t
will be inherited from by a class that will in fact contain a value_
data member.
Here's what it would look like:
template<class T, template<class...> class... Ops> // functions compatible with T
struct viewer : public Ops<viewer<T>>... // available functions are inherited
{
viewer(T const& value) noexcept : value_{ value } {}
T const& value_;
};
It could then be used like this:
std::string str{ "abc" };
viewer<std::string, size_op_t/*other operations like begin_op_t, etc.*/> view{ str };
std::cout << view.size() << '\n'; // only provides the `size()` operation
I'm trying to avoid having to store a reference in every xyz_op_t
while having the ability to easily create custom viewer-like types from generic functors like size_op_t
that I can mix and match depending on what operations I want available.