我试图设置类成员的类型,而不是通过模板参数传递它。
详细信息:
// Forward declaration:
class A;
class B;
class Base
{
};
template <class T>
class Derived : public Base
{
private:
T2 var;
};
其中 T 可以是 class A
或 class B
.
我想做的是 Derived<A>
T2 是 int(例如)并且对于 Derived<B>
T2 是双倍的(例如)。我想避免以下解决方案:
template <class T1, class T2>
class Derived : public Base
{
private:
T2 var;
};
我想避免这种情况,因为对于 Derived<A>
T2 可能有多种可能的组合:Derived<A,int>
, Derived<A,double>
, ...
我想要的是T2的类型对于整个Derived<A>
都是唯一的.
知道如何解决吗?
最佳答案
更新:评论表明您试图解决的原始问题并未在问题中得到完整解释。尽管如此,我还是会在这个答案的底部留下原来的答案。
你不能有两个 Derived<A>
var
的不同类型 T2成员。另外,用户定义的变量不能影响成员变量的类型。变量值在运行时设置,类型在编译时确定。
要存储用户以某种方式定义的类型,您必须将变量限制为一组已知类型,或者使用一种包含变量内容的序列化版本的类型。已知类型集通常用于数据库上下文中,其中字段可以具有几种预定义类型(例如字符串、整数、 bool 值、 double 类型)中的一种。成员变量的类型可以是一个 Boost.Variant,仅限于该类型的 C++ 表示。 “用户定义类型”的另一个应用是您的程序的用户必须以某种方式定义类型及其对象的布局和解释,例如,如果您的程序是某种脚本语言的解释器。在那种情况下,再次可以使用 Boost.Variant(或类似的东西),或者,由于该值可能是某些用户提供的输入,只需将序列化值存储在字符串中并在每次必须处理它时对其进行解释。
原答案:
这通常是通过模板元编程完成的,在本例中是类型函数(有时,根据上下文,特征或策略类的一部分):
template <class T>
struct DerivedMemVarType {
typedef double type; //default
};
template<>
struct DerivedMemVarType<A> {
typedef int type;
};
然后:
template <class T>
class Derived : public Base
{
typedef typename DerivedMemVarType<T>::type T2;
private:
T2 var;
};
您也可以省略默认值,以便 Derived
的任何实例化对于您尚未在函数中映射的类型,将给出编译错误:
template <class T>
struct DerivedMemVarType; //default is not defined
template<>
struct DerivedMemVarType<A> {
typedef int type;
};
template<>
struct DerivedMemVarType<B> {
typedef double type;
};
//...
Derived<C> dc; // ...template error mess....
// --> error: invalid use of incomplete type 'struct DerivedMemVarType<C>'
关于c++定义没有模板参数的成员类的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22245180/