end*_*gin 23 c++ templates types
我正在尝试解决由对象(称为Diagram)组成的编程问题,该对象包含多个参数.每个参数(Parameter类)可以是以下几种类型之一:int,double,complex,string - 仅举几例.
所以我的第一直觉是将我的Diagram类定义为具有模板参数的向量,这看起来像这样.
class Diagram
{
private:
std::vector<Parameter<T> > v;
};
Run Code Online (Sandbox Code Playgroud)
这不编译,我理解为什么.因此,根据此页面上的建议如何声明作为类中任何类型的对象的数据成员,我修改了我的代码,如下所示:
class ParameterBase
{
public:
virtual void setValue() = 0;
virtual ~ParameterBase() { }
};
template <typename T>
class Parameter : public ParameterBase
{
public:
void setValue() // I want this to be
// void setValue(const T & val)
{
// I want this to be
// value = val;
}
private:
T value;
};
class Diagram
{
public:
std::vector<ParameterBase *> v;
int type;
};
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何使用适当的模板化参数调用setValue函数.在ParameterBase抽象基类中不可能有模板化参数.任何帮助是极大的赞赏.
PS我没有使用boost :: any的灵活性.
Moo*_*uck 30
你非常接近.我添加了一些因为它们很方便
class ParameterBase
{
public:
virtual ~ParameterBase() {}
template<class T> const T& get() const; //to be implimented after Parameter
template<class T, class U> void setValue(const U& rhs); //to be implimented after Parameter
};
template <typename T>
class Parameter : public ParameterBase
{
public:
Parameter(const T& rhs) :value(rhs) {}
const T& get() const {return value;}
void setValue(const T& rhs) {value=rhs;}
private:
T value;
};
//Here's the trick: dynamic_cast rather than virtual
template<class T> const T& ParameterBase::get() const
{ return dynamic_cast<const Parameter<T>&>(*this).get(); }
template<class T, class U> void ParameterBase::setValue(const U& rhs)
{ return dynamic_cast<Parameter<T>&>(*this).setValue(rhs); }
class Diagram
{
public:
std::vector<ParameterBase*> v;
int type;
};
Run Code Online (Sandbox Code Playgroud)
然后,图表可以执行以下操作:
Parameter<std::string> p1("Hello");
v.push_back(&p1);
std::cout << v[0]->get<std::string>(); //read the string
v[0]->set<std::string>("BANANA"); //set the string to something else
v[0]->get<int>(); //throws a std::bad_cast exception
Run Code Online (Sandbox Code Playgroud)
看起来你的意图是在向量中存储资源拥有的指针.如果是这样,请小心使其Diagram具有正确的析构函数,并使其不可复制,并且不可复制.
该波纹管实现使用了一些C ++ 11功能,但您可以将它们分开。
#include <vector>
#include <memory>
class Parameter
{
private:
class ParameterBase {
public:
virtual ~ParameterBase() {}
virtual ParameterBase* copy() = 0;
virtual void foo() = 0;
};
template <typename T>
class ParameterModel : public ParameterBase {
public:
// take by value so we simply move twice, if movable
ParameterModel(const T& t) : t(t) {}
ParameterModel(T&& t) : t(t) {}
void foo() { t.foo(); }
ParameterModel* copy() { return new ParameterModel(*this); }
private:
T t;
};
public:
template <typename T>
Parameter(T&& t)
: pp(new ParameterModel< typename std::remove_reference<T>::type >(std::forward<T>(t))) {}
// Movable and Copyable only
Parameter(Parameter&&) = default;
Parameter& operator=(Parameter&&) = default;
Parameter(const Parameter& other) : pp(other.pp->copy()) {};
Parameter operator=(const Parameter& other) {
pp.reset(other.pp->copy());
return *this;
};
// members
void foo() { pp->foo(); }
private:
std::unique_ptr<ParameterBase> pp;
};
class Diagram
{
public:
std::vector<Parameter> v;
int type;
};
struct X {
void foo() {}
};
struct Y {
void foo() {}
};
int main()
{
Diagram d;
d.v.emplace_back(X()); // int
// parameters are copyable and can be reassigned even with different
// impls
Parameter p = d.v.back();
Parameter other((Y()));
other = p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该代码的作用是什么?它掩盖了我们使用继承来实现用户参数的事实。他们需要知道的就是我们需要一个名为的成员函数foo。这些要求在我们的文档中表达ParameterBase。您需要确定这些要求并将其添加到中ParameterBase。这基本上是一个更严格的限制boost::any。
它也与Sean Parent的价值语义学演讲中描述的内容非常接近。
| 归档时间: |
|
| 查看次数: |
60191 次 |
| 最近记录: |