[英]c++ defining type of a member class without template argument
I am trying to set the type of the member of a class, without passing it through template argument. 我试图设置类的成员的类型,而不通过模板参数传递它。
In details: 详情如下:
// Forward declaration:
class A;
class B;
class Base
{
};
template <class T>
class Derived : public Base
{
private:
T2 var;
};
where T could be either class A
or class B
. 其中T可以是
class A
class B
或class B
。 What I would like to do is for Derived<A>
T2 is int (for instance) and for Derived<B>
T2 is double (for instance). 我想要做的是
Derived<A>
T2是int(例如),而Derived<B>
T2是double(例如)。 I would like to avoid the following solution: 我想避免以下解决方案:
template <class T1, class T2>
class Derived : public Base
{
private:
T2 var;
};
I want to avoid this because for Derived<A>
there could be various possible combinations for T2: Derived<A,int>
, Derived<A,double>
, ... 我想避免这种情况,因为对于
Derived<A>
,T2可能有各种可能的组合: Derived<A,int>
, Derived<A,double>
,...
What I want is that the type of T2 is unique for the entire Derived<A>
. 我想要的是T2的类型对于整个
Derived<A>
是唯一的。
Any idea how to solve that ? 知道如何解决这个问题吗?
Update: The comments show that the original problem you are trying to solve is not completely explained in the question. 更新:评论显示您尝试解决的原始问题未在问题中完整解释。 I'll leave the original answer nevertheless at the bottom of this answer.
不过,我会在这个答案的底部留下原始答案。
You cannot have two Derived<A>
with different types T2 for the var
member. 对于
var
成员,不能有两个具有不同类型T2的Derived<A>
。 In addition, a variable defined by the User can not influence the type of the member variable . 此外, User定义的变量不能影响成员变量的类型 。 Variable values are set at runtime, types are determined at compiletime.
变量值在运行时设置,类型在编译时确定。
To store a type somehow defined by the user, you will have either have to restrict the variable to a set of known types or use one type that contains a serialized version of the variable's content. 要以某种方式存储由用户定义的类型,您必须将变量限制为一组已知类型,或者使用包含变量内容的序列化版本的一种类型。 The set of known types is often used in the context of databases, where the fields can have one of several predefined types (eg String, Integer, Boolean, Double).
已知类型的集合通常在数据库的上下文中使用,其中字段可以具有若干预定义类型之一(例如,String,Integer,Boolean,Double)。 The type for the member variable then could be a Boost.Variant, restricted to C++ representations of that type.
然后,成员变量的类型可以是Boost.Variant,仅限于该类型的C ++表示。 Another application of "user defined types" are where the user of your program has to somehow define the layout and interpretation of the type and its object, for example if your program is the interpreter of some scripting language.
“用户定义类型”的另一个应用是程序用户必须以某种方式定义类型及其对象的布局和解释,例如,如果您的程序是某种脚本语言的解释器。 In that case again a Boost.Variant (or something similar) can be of use, or, since the value is probably some user provided input, just store the serialized value in a string and interpret it every time you have to deal with it.
在这种情况下,可以使用Boost.Variant(或类似的东西),或者,由于该值可能是某些用户提供的输入,只需将序列化值存储在字符串中,并在每次处理它时对其进行解释。
This is usually done via template metaprogramming, in this case a type function (sometimes, depending on the context, part of a traits or policy class): 这通常通过模板元编程来完成,在这种情况下是一个类型函数(有时,取决于上下文,特征或策略类的一部分):
template <class T>
struct DerivedMemVarType {
typedef double type; //default
};
template<>
struct DerivedMemVarType<A> {
typedef int type;
};
And then: 然后:
template <class T>
class Derived : public Base
{
typedef typename DerivedMemVarType<T>::type T2;
private:
T2 var;
};
You can also leave out the default, so that any instantiation of Derived
for a type that you have not mapped in your function will give a compile error: 您也可以省略默认值,这样对于您未在函数中映射的类型的任何
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>'
if you do not have any type specific function call, you can use something like... 如果你没有任何类型特定的函数调用,你可以使用像...
class A;
class B;
class Base
{
};
template <class T>
class Derived : public Base
{
public:
Derived(T startVal):var(startVal){}
private:
T var;
};
template <typename T>
Derived<T> MakeDerived(T initValue)
{
return Derived<T>(initValue);
}
and now you can use it the following and the compiler should know what type you are passing to the function. 现在您可以使用以下内容,编译器应该知道您传递给函数的类型。
int initialValue = 0;
auto derived = MakeDerived(initialValue);
I think you can create a separate class that just holds a typedef which you then specialize and use in your Derived class. 我认为你可以创建一个单独的类,它只包含一个typedef,然后你可以在Derived类中专门使用它。
template<typename T>
class VarType {
public:
typedef int TheType;
}
template <>
class VarType<B> {
public:
typedef double TheType;
};
template <typename T>
class Derived : public Base {
private:
typename VarType<T>::TheType var;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.