在下面的代码中,C的基类B1的模板参数OFFSET取决于B0和B1上的B2。
这是通过在每次创建C实例时(在main方法中)手动编写代码来完成的。有没有办法将此功能转移到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,其中T定义类型T&lt; 2&gt;
使用boost :: mpl :: times计算新的偏移量
添加更多模板魔术......
答案 0 :(得分:1)
如何定义帮助程序类:
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
左右......)
答案 1 :(得分:1)
你可以用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;
}