是否可以通过mpl?
解决在运行时选择参数的以下情况struct A {
A(int number) { /* use number */ } };
struct B { };
template <typename T, int n>
struct A_or_B_Holder {
A_or_B_Holder() : _t( /* void or 'n', depends on T */ ) { }
private:
T _t;
};
A_or_B_Holder<B, void> b;
A_or_B_Holder<A, 3> a;
理想地,
A_or_B_Holder<B> b;
A_or_B_Holder<A, 3> a;
答案 0 :(得分:1)
你的第一个问题是void
是一个类型,而不是一个整数。您可以让模板接受两种类型,第二种是boost::mpl::int_
或void
。
然后你可以专门化整个结构,或者你可以将数据成员放在基类中并专门化它。
#include <boost/mpl/int.hpp>
struct A {
A(int number) { /* use number */ } };
struct B { };
template <class T, class Value>
struct A_or_B_Holder_Base{
A_or_B_Holder_Base(): _t(Value::value) {}
protected:
T _t;
};
template <class T>
struct A_or_B_Holder_Base<T, void> {
A_or_B_Holder_Base(): _t() {}
protected:
T _t;
};
template <typename T, typename Value>
struct A_or_B_Holder : public A_or_B_Holder_Base<T, Value> {
};
using boost::mpl::int_;
A_or_B_Holder<A, int_<3> > x;
A_or_B_Holder<B, void> y;
A_or_B_Holder<A, void > w; //error, no default constructor
A_or_B_Holder<B, int_<3> > z; //error, no int constructor
更自然的可能不是要求参数是编译时常量(因为你正在将编译时常量转换为运行时变量)。只需重载构造函数。
struct A {
A(int number) { /* use number */ } };
struct B { };
template <typename T>
struct A_or_B_Holder {
A_or_B_Holder() : _t( ) { }
A_or_B_Holder(int number): _t(number) {}
private:
T _t;
};
A_or_B_Holder<B> b;
A_or_B_Holder<A> a(3);
答案 1 :(得分:0)
我认为在运行时传递不同的参数是不可能的。你必须有一个所有T类型都有的标准构造函数。您可以从std::vector<void*>
构造所有T类型,并使用它来传递可变数量的变量类型参数,但是 super 是危险的。
但是,您的示例似乎实际上是在编译时决定,而不是运行时,这是可以解决的。
const int NO_INT_PARAM=INT_MIN;
template <typename T, int n>
struct A_or_B_Base {
A_or_B_Holder() : _t(n) { }
private:
T _t;
};
template <typename T>
struct A_or_B_Base<T, NO_INT_PARAM> {
A_or_B_Holder() : _t() { }
private:
T _t;
};
template <typename T, int n=NO_INT_PARAM>
struct A_or_B_Holder : A_or_B_Base<T, n>{
A_or_B_Holder() : A_or_B_Base() { }
/* other functions*/
};
A_or_B_Holder<A, 3> a; //uses A(3) constructor
A_or_B_Holder<B> b; //uses B() constructor
A_or_B_Holder<A> c; //compiler error! A() doesn't exist!
A_or_B_Holder<B, 5> d; //compiler error! B(5) doesn't exist!
A_or_B_Holder<B, NO_INT_PARAM> e; //same as b, uses B() constructor
答案 2 :(得分:0)
您可以使用Boost.Variant
#include <boost/variant.hpp>
struct A
{
};
struct B
{
B(int)
{
}
};
int main()
{
boost::variant<A, B> val;
if (/*some condition*/)
{
val = A();
}
else
{
val = B(5);
}
}
如果您对如何实现这一点感兴趣,而不是您可以使用的内容,我建议您查看Boost.Any
和Boost.Variant
的实现。