Initialize a tuple through an inheritance tree
Let class B be the base of A:
class B
{
public:
std::tuple<int, bool, float> properties.
}
class A : public B
{
public:
std::tuple<float, std::string, std::string> derivedProperties.
}
Is there a way to add a set of derived derived tuples to a tuple of basic propositions? For example, some form of CRTP? I know that the properties of the base class and derived types are known at compile time, but I cannot figure out how to combine properties of different levels of inheritance.
source to share
You almost had it when you thought about CRTP.
You can do the following:
// We need this boilerplate to overcome
// the incompleteness of "Derived" when instantiating "Base<Derived>"
template <typename T>
struct properties {
using type = std::tuple<>;
};
class Derived;
template <>
struct properties<Derived> {
using type = std::tuple<float, std::string, std::string>;
};
// Now that we defined our properties
template <typename Derived>
class Base {
public:
using derived_properties_t = typename properties<Derived>::type; // Should be a tuple
using base_properties_t = std::tuple<int, bool, float>;
using combined_properties_t = decltype(std::tuple_cat(std::declval<base_properties_t>(),
std::declval<derived_properties_t>()));
combined_properties_t properties;
};
class Derived : public Base<Derived> {
public:
using properties_type = std::tuple<float, std::string, std::string>;
};
You can see a working demo at Coliru
source to share
You can use variadic templates to add more types to properties
your base class element ( B
). If you want to have base class constructors in a derived class, you can use using-declaration :
#include <string>
#include <tuple>
template<typename... Ts>
class B {
public:
B(int i, bool b, float f, const Ts&... rest) :
properties(std::make_tuple(i, b, f, rest...)) {
}
std::tuple<int, bool, float, Ts...> properties;
};
class A : public B<float, std::string, std::string> {
using B::B;
};
int main() {
A foo(12, true, 3.14, 6.28, "foo", "bar");
}
Passing derived classes class B
to the same function can be achieved using function templates:
template<typename... Ts>
void test(const B<Ts...>& base);
source to share