让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?我知道基类和派生类型的属性在编译时是已知的,但我似乎无法弄清楚如何组合不同继承级别的属性。
答案 0 :(得分:3)
您可以使用variadic templates向基类的properties
成员添加更多类型(B
)。如果您希望在派生类中也有基类的构造函数,可以使用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");
}
可以通过函数模板实现将class B
的派生类传递给同一函数:
template<typename... Ts>
void test(const B<Ts...>& base);
答案 1 :(得分:2)
如果相关,您可以使用以下内容:
template <typename ... Ts>
class C
{
public:
std::tuple<int, bool, float, Ts...> properties.
};
using B = C<>;
using A = C<float, std::string, std::string>;
答案 2 :(得分:1)
当你想到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
上看到有效的演示