C++ C++;虚拟模板法
我有一个抽象类(我知道它不会以这种方式编译,但它是为了理解我想做的事情):C++ C++;虚拟模板法,c++,templates,virtual,C++,Templates,Virtual,我有一个抽象类(我知道它不会以这种方式编译,但它是为了理解我想做的事情): 类抽象计算{ 公众: 模板虚拟void setData(std::string id,T data); 模板虚拟getData(std::string id); }; 类计算:公共抽象计算{ 公众: 模板void setData(std::string id,T data); 模板T getData(std::string id,T data); }; 因此,当我调用setData(“foodoull”,data)时,
类抽象计算{
公众:
模板虚拟void setData(std::string id,T data);
模板虚拟getData(std::string id);
};
类计算:公共抽象计算{
公众:
模板void setData(std::string id,T data);
模板T getData(std::string id,T data);
};
因此,当我调用setData(“foodoull”,data)
时,我希望将foodoull
标识的double(这里主要关注的不是内部机制)设置为double数据
那怎么做呢
我认为可能有一种方法是键入类似于
virtualvoidsetdata(std::stringid,double data)
的内容,但我不知道如何操作。使用boost::any
接受数据,然后在实际设置时,从中获取正确的类型。您可能可以在您的案例中使用
virtual void setData(std::string id, boost::any data);
它是一个可以封装几乎任何东西的包装器
.首先,您不能使用
虚拟的
模板功能。由于模板是在编译时解析的,virtual
将不起作用,因为编译器不知道选择哪个模板。有关这方面的更多信息,请参阅。问题在于,您无法轻松地将静态时间多态性(模板)与运行时多态性混合使用。在您的示例中,该语言不允许特定构造的原因是,可能有无限多个不同的类型可以实例化模板成员函数,这反过来意味着编译器必须生成代码来动态分派这些类型,这是不可行的
这里可以做不同的事情来绕过限制,基本上可以去掉静态多态性或动态多态性。从等式中删除动态多态性可以通过提供一个非派生的类型来完成,以存储
映射,然后提供只在基本级别解析该映射的模板:
class AbstractComputation {
public:
template <typename T>
void setData( std::string const & id, T value ) {
m_store.setData( id, value );
}
template <typename T>
T getData( std::string const & id ) const {
return m_store.getData<T>( id );
}
protected:
ValueStore m_store;
};
类型擦除是如何在后台实现的很有意思,但在本文的范围之外,重要的部分是
boost::any
是一种具体的(非模板化的)类型,可以通过在参数上使用类型擦除在内部存储任何类型,同时允许对数据进行类型安全检索。如果您事先知道可能的类型列表,预处理器可能会帮助您:
#define MY_CLASSES MYTYPE(int) MYTYPE(float) MYTYPE(double)
class AbstractComputation {
public:
# define MYTYPE(T) virtual void setData(std::string id, T data)=0;\
virtual void getData(std::string id, T& dst_data)=0;
MY_CLASSES
# undef MYTYPE
};
class Computation : public AbstractComputation {
public:
# define MYTYPE(T) virtual void setData(std::string id, T data){std::cout<<"writing: "<<data<<std::endl;}\
virtual void getData(std::string id, T& dst_data){dst_data=0;/*put your actual implementation here*/}
MY_CLASSES
# undef MYTYPE
};
#定义我的类MYTYPE(int)MYTYPE(float)MYTYPE(double)
类抽象计算{
公众:
#定义MYTYPE(T)虚拟void setData(std::string id,T data)=0\
虚拟void getData(std::string id,T&dst_data)=0;
我的课程
#未定义MYTYPE
};
类计算:公共抽象计算{
公众:
#定义MYTYPE(T)虚拟void setData(std::string id,T data){std::cout在某些情况下,将模板从方法级别移动到类级别就足够了,例如:
#include <iostream>
template<typename T>
class AbstractComputation {
public:
virtual void setData(std::string id, T data)
{
std::cout << "base" << std::endl;
}
};
template<typename T>
class Computation : public AbstractComputation<T> {
public:
virtual void setData(std::string id, T data)
{
std::cout << "derived" << std::endl;
}
};
int main()
{
AbstractComputation<int> *x = new Computation<int>();
x->setData("1", -1);
delete x;
return 0;
}
#包括
模板
类抽象计算{
公众:
虚拟void setData(std::string id,T data)
{
std::cout是关于如何为double创建一个特例的问题。或者如何通过使用一个模板函数来通用地设置任何数据类型。如果一个类型有两个名为“set data”和“get data”的方法,那么可能的重复就是“抽象计算”首先,您可以想到何时命名该类型?我喜欢使用boost::any
的方法,但不喜欢添加对boost的依赖。但令人高兴的是,六年后c++17
向该语言添加了(和)。我最终使用std::any
跨任意用户定义的类型创建了一个API。
#define MY_CLASSES MYTYPE(int) MYTYPE(float) MYTYPE(double)
class AbstractComputation {
public:
# define MYTYPE(T) virtual void setData(std::string id, T data)=0;\
virtual void getData(std::string id, T& dst_data)=0;
MY_CLASSES
# undef MYTYPE
};
class Computation : public AbstractComputation {
public:
# define MYTYPE(T) virtual void setData(std::string id, T data){std::cout<<"writing: "<<data<<std::endl;}\
virtual void getData(std::string id, T& dst_data){dst_data=0;/*put your actual implementation here*/}
MY_CLASSES
# undef MYTYPE
};
#include <iostream>
template<typename T>
class AbstractComputation {
public:
virtual void setData(std::string id, T data)
{
std::cout << "base" << std::endl;
}
};
template<typename T>
class Computation : public AbstractComputation<T> {
public:
virtual void setData(std::string id, T data)
{
std::cout << "derived" << std::endl;
}
};
int main()
{
AbstractComputation<int> *x = new Computation<int>();
x->setData("1", -1);
delete x;
return 0;
}