更改派生类的模板参数
Changing the template arguments of derived classes
在下面的代码中,C的基类B1的模板参数OFFSET依赖于B0,B2依赖于B1。
这是通过每次创建C实例时手动编写代码来完成的(在主方法中)。有没有办法将这个功能转移到C的定义中?
template<int OFFSET>
struct A {
enum O { offset = OFFSET };
enum S { size = 2 };
};
template<int OFFSET>
struct B {
enum O { offset = OFFSET };
enum S { size = 4 };
};
template < typename B0, typename B1, typename B2 >
struct C : public B0, B1, B2 {
};
int main(int argc, const char *argv[])
{
// instance of C
C< A<1>,
B< A<1>::offset * A<1>::size >,
A<
B< A<1>::offset * A<1>::size >::offset *
B< A<1>::offset * A<1>::size >::size
>
> c1;
// does the same thing
C< A<1>,
B< A<1>::size >,
A<
A<1>::size *
B< A<1>::size >::size
>
> c2;
return 0;
}
编辑:
为了回答这些评论,我认为需要采取以下步骤来解决这个问题:
编写一个可以更改偏移量的元函数:set_ new_ offset;2>
使用boost::mpl::times计算新偏移
添加更多模板魔术。。。
您可以使用C中的模板模板来实现这一点,尽管我不是100%相信这是一个改进。如果你只需要三个垒,这应该没问题。如果你需要任意数量的基数。。。必须有比继承更好的方法来做到这一点,因为这种方法会变得笨拙。
template<int OFFSET>
struct A {
enum O { offset = OFFSET };
enum S { size = 2 };
};
template<int OFFSET>
struct B {
enum O { offset = OFFSET };
enum S { size = 4 };
};
template < typename B0, template <int T> class B1, template <int T> class B2 >
struct C : public B0, B1<B0::offset * B0::size>, B2<B1<B0::offset * B0::size>::offset * B1<B0::offset * B0::size>::size> {
enum
{
B0_offset = B0::offset,
B1_offset = B1<B0::offset * B0::size>::offset,
B2_offset = B2<B1<B0::offset * B0::size>::offset * B1<B0::offset * B0::size>::size>::offset,
B0_size = B0::size,
B1_size = B1<B0::offset * B0::size>::size,
B2_size = B2<B1<B0::offset * B0::size>::offset * B1<B0::offset * B0::size>::size>::size
};
};
int main()
{
// instance of C
C< A<1>,
B,
A
> c1;
static_cast<void>(c1);
// does the same thing
C< A<1>,
B,
A
> c2;
static_cast<void>(c2);
std::cout << c1.B0_offset << std::endl;
std::cout << c1.B1_offset << std::endl;
std::cout << c1.B2_offset << std::endl;
std::cout << c1.B0_size << std::endl;
std::cout << c1.B1_size << std::endl;
std::cout << c1.B2_size << std::endl;
std::cout << c2.B0_offset << std::endl;
std::cout << c2.B1_offset << std::endl;
std::cout << c2.B2_offset << std::endl;
std::cout << c2.B0_size << std::endl;
std::cout << c2.B1_size << std::endl;
std::cout << c2.B2_size << std::endl;
return 0;
}
如何定义一个辅助类:
template <template <int> class C, int N>
struct Composer
{
enum O { offset = C<N>::offset * C<N>::size; };
enum S { size = C<N>::size; };
};
然后你可以说:
C<A<1>, Composer<A, 1>, Composer<B, Composer<A, 1>::offset> c2;
如果有必要,可以想出一个更高阶的作曲家,让你形成更高的"力量"。
(也许Composer
应该被称为Bind1st
左右…)
相关文章:
- 在派生函数中指定void*参数
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 创建派生自可变参数模板包的类型元组
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- C++派生类重载函数(带有 std::function 参数)不可见
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 从模板参数派生的类
- C++ 如何使派生类自动获取基类参数
- C++ 将派生类的成员函数指针作为参数传递时选择了错误的模板专用化
- 如何在派生类中正确覆盖具有不同参数的函数?
- 根据参数创建派生类的新实例
- 具有派生参数的函数重写
- 将派生类作为参数传递给方法,该方法是具有智能指针的基类
- 将方法参数类型更改为子类中的派生类
- 派生类的模板参数推导
- 将派生类构造函数参数传递给受保护的成员
- 具有原始方法参数派生类的 C++ 重载方法参数