我想有一个可变的类模板来生成每种类型的一个方法,例如像下面这样的类模板:
template <class T, class ... Ts>
class MyClass {
public:
virtual void hello(const T& t) = 0;
};
将使方法你好(const双
请注意,我希望该类是纯抽象的,因此派生类实际上需要进行实现,例如:
class Derived : MyClass<double, int> {
public:
inline void hello(const double& t) override { }
inline void hello(const int& t) override { }
};
这个问题和这个问题有点相似,但是我不明白如何使它适应我的情况。
编辑
递归继承对我来说似乎是正确的解决方案。这种更复杂的情况怎么样,超类有不止一个方法,模板参数是强制性的?以下是我尝试过的(但我得到了错误):
template <class MandatoryT, class OptionalT, class... MoreTs>
class MyClass : public MyClass<MandatoryT, MoreTs...> {
public:
virtual ~MyClass() {}
virtual char* goodmorning(const MandatoryT& t) = 0;
virtual bool bye(const MandatoryT& t,
const std::map<std::string,bool>& t2) = 0;
using MyClass<MandatoryT, MoreTs...>::hello;
virtual void hello(const OptionalT& msg) = 0;
};
template <class MandatoryT, class OptionalT>
class MyClass<MandatoryT, OptionalT> {
virtual void processSecondaryMessage(const OptionalT& msg) = 0;
};
template <class MandatoryT>
class MyClass<MandatoryT> {
virtual void processSecondaryMessage() = 0;
}
}
基本上我想要的是派生类应该有一个或多个类型。第一种方法用于其他方法,而从第二种方法开始,它应用于
hello()
。如果只提供一种类型,则调用空的hello()
。但是当至少提供了第二种类型时,hello()
应该使用它。
上面的代码抱怨至少应该有两个模板参数,因为有“两个”基例而不是一个。
也许其他人可以做得更好,但我认为只有两种方法
>
递归继承
您可以如下递归地定义MyClass
// recursive case
template <typename T, typename ... Ts>
struct MyClass : public MyClass<Ts...>
{
using MyClass<Ts...>::hello;
virtual void hello (const T&) = 0;
};
// ground case
template <typename T>
struct MyClass<T>
{ virtual void hello (const T&) = 0; };
或
变异遗传
您可以定义另一个类/结构,比如说MyHello
,它声明一个hello()
方法,并可变地从MyClass
继承它。
template <typename T>
struct MyHello
{ virtual void hello (const T&) = 0; };
template <typename ... Ts>
struct MyClass : public MyHello<Ts>...
{ };
递归示例与类型冲突兼容(也就是说:当一个类型在模板参数列表MyClass
中出现更多时间时也有效;通过示例MyClass
不幸的是,可变遗传案例并非如此。
下面是一个完整的编译示例
#if 1
// recursive case
template <typename T, typename ... Ts>
struct MyClass : public MyClass<Ts...>
{
using MyClass<Ts...>::hello;
virtual void hello (const T&) = 0;
};
// ground case
template <typename T>
struct MyClass<T>
{ virtual void hello (const T&) = 0; };
#else
template <typename T>
struct MyHello
{ virtual void hello (const T&) = 0; };
template <typename ... Ts>
struct MyClass : public MyHello<Ts>...
{ };
#endif
struct Derived : public MyClass<double, int>
{
inline void hello (const double&) override { }
inline void hello (const int&) override { }
};
int main()
{
Derived d;
d.hello(1.0);
d.hello(2);
}
--编辑--
OP问道
如果MyClass有多个方法,并且我总是需要一个模板参数(请参见编辑的问题),那么更复杂的情况如何?
从你的问题来看,我不明白你到底想要什么。
但是,假设您想要一个纯虚拟方法,比如说,
goodmorning()
接收MandT
(强制类型),对于MandT
之后的每个类型,都需要一个纯虚拟方法hello()
,或者当MandT
之后的列表为空时,不带参数的hello()
。
一个可能的解决方案如下
// declaration and groundcase with only mandatory type (other cases
// intecepted by specializations)
template <typename MandT, typename ...>
struct MyClass
{
virtual void hello () = 0;
virtual ~MyClass () {}
virtual char * goodmorning (MandT const &) = 0;
};
// groundcase with a single optional type
template <typename MandT, typename OptT>
struct MyClass<MandT, OptT>
{
virtual void hello (OptT const &) = 0;
virtual ~MyClass () {}
virtual char * goodmorning (MandT const &) = 0;
};
// recursive case
template <typename MandT, typename OptT, typename ... MoreOptTs>
struct MyClass<MandT, OptT, MoreOptTs...>
: public MyClass<MandT, MoreOptTs...>
{
using MyClass<MandT, MoreOptTs...>::hello;
virtual void hello (OptT const &) = 0;
virtual ~MyClass () {}
};
这里的递归比以前稍微复杂一些。
如果您仅使用强制类型实例化
MyClass
(例如:MyClass)
如果您实例化一个
MyClass
与一个可选类型(如MyClass
如果你实例化一个
MyClass
有两个或更多可选类型(比如MyClass
注意,我将
goodmorning()
放在两种基本情况下,因为您不需要递归地定义它。
下面是一个完整的编译示例
// declaration and groundcase with only mandatory type (other cases
// intecepted by specializations)
template <typename MandT, typename ...>
struct MyClass
{
virtual void hello () = 0;
virtual ~MyClass () {}
virtual char * goodmorning (MandT const &) = 0;
};
// groundcase with a single optional type
template <typename MandT, typename OptT>
struct MyClass<MandT, OptT>
{
virtual void hello (OptT const &) = 0;
virtual ~MyClass () {}
virtual char * goodmorning (MandT const &) = 0;
};
// recursive case
template <typename MandT, typename OptT, typename ... MoreOptTs>
struct MyClass<MandT, OptT, MoreOptTs...>
: public MyClass<MandT, MoreOptTs...>
{
using MyClass<MandT, MoreOptTs...>::hello;
virtual void hello (OptT const &) = 0;
virtual ~MyClass () {}
};
struct Derived0 : public MyClass<char>
{
void hello () override { }
char * goodmorning (char const &) override
{ return nullptr; }
};
struct Derived1 : public MyClass<char, double>
{
void hello (double const &) override { }
char * goodmorning (char const &) override
{ return nullptr; }
};
struct Derived2 : public MyClass<char, double, int>
{
void hello (double const &) override { }
void hello (int const &) override { }
char * goodmorning (char const &) override
{ return nullptr; }
};
int main()
{
Derived0 d0;
Derived1 d1;
Derived2 d2;
d0.hello();
d0.goodmorning('a');
d1.hello(1.2);
d1.goodmorning('b');
d2.hello(3.4);
d2.hello(5);
d2.goodmorning('c');
}
我有一个模板类,其中每个模板参数代表内部计算可以处理的一种类型的值。需要模板(而不是函数重载),因为值被作为::any传递,并且它们的类型在运行时之前不清楚。 为了正确地转换为正确的类型,我希望每个变量参数类型都有一个成员列表,类似于这样: 或者,我想将模板参数类型存储在一个列表中,以便对其进行RTTI处理(?)。但如何将它们保存在std::initializer\u列表成员中,我也不清楚。 谢谢
我试图从一组可变的模板类(其中每个类都有一个非类型参数)中恢复非typename模板参数,以便在另一种类型中将它们用作整数序列。 下面的代码显示了我所拥有的。整数序列/成员序列是从元组中抄袭出来的。 和的类型是
变量通用属性 变量通用属性有title,value,type,tip,rule,message,除了通用属性个别变量还有其它属性,请看每个具体控件; "vars": { "varName1": { "title": "测试 text", /*后台设置时 input 的 label*/ "value": "1", /*变量默认值*/ "type
变量通用属性 变量通用属性有title,value,type,tip,rule,message,除了通用属性个别变量还有其它属性,请看每个具体控件; "vars": { "varName1": { "title": "测试 text", /*后台设置时 input 的 label*/ "value": "1", /*变量默认值*/ "type
我是新使用模板。作为标题,我有一个非模板类(Obj和ObjBase)和一个模板类pitem。我想让pItem::RefValue()访问obj中的私有成员。 我想下面的行得通: 它不: 错误C2248:“obj::GetValue”:无法访问类“obj”中声明的私有成员 注意:请参阅对正在编译的函数模板实例化“int PItem::GetValue(void)”的引用 编译器投诉:
我有以下xml类型: FaxNumber类型如下所示: 生成的xml应该如下所示: 运行JAXB XJC从XSD生成java类时,它会生成以下类: 但是,我想绑定FaxNumber到这样的复合类: 有没有办法在JAXB绑定xml中定义这样的绑定? 注意:不幸的是,我无法控制并且无法更改XSD