跨继承树初始化元组

Initialize tuple across inheritance tree

本文关键字:元组 初始化 继承      更新时间:2023-10-16

让类 B 是 A 的基:

class B
{
public:
std::tuple<int, bool, float> properties.
}
class A : public B
{
public:
std::tuple<float, std::string, std::string> derivedProperties.
}

有没有办法将派生属性元组添加到基本元组?例如通过某种形式的 CRTP?我知道基类和派生类型的属性在编译时是已知的,但我似乎无法弄清楚如何组合不同继承级别的属性。

可以使用可变参数模板向基类的properties成员添加更多类型(B(。如果你也希望在派生类中拥有基类的构造函数,你可以使用 using-声明:

#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");
}

class B的派生类传递给同一函数可以通过函数模板实现:

template<typename... Ts>
void test(const B<Ts...>& base);

现场演示

如果相关,您可以使用以下内容:

template <typename ... Ts>
class C
{
public:
std::tuple<int, bool, float, Ts...> properties.
};
using B = C<>;
using A = C<float, std::string, std::string>;

当你想到CRTP时,你几乎拥有它。

您可以执行以下操作:

// 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>;
};

您可以在Coliru上看到工作演示