首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有模板成员变量的C++类

具有模板成员变量的C++类
EN

Stack Overflow用户
提问于 2012-12-21 04:42:22
回答 2查看 83.5K关注 0票数 29

我正在尝试解决一个由一个对象(称为Diagram)组成的编程问题,该对象包含几个参数。每个参数( parameter类)可以是几种类型中的一种: int、double、complex、string等等。

因此,我的第一个直觉是将我的Diagram类定义为具有模板参数的向量,如下所示。

代码语言:javascript
运行
复制
class Diagram
{
private:
    std::vector<Parameter<T> > v;
};

这不能编译,我理解其中的原因。因此,根据这个页面How to declare data members that are objects of any type in a class上的建议,我修改了我的代码,如下所示:

代码语言:javascript
运行
复制
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;
};

我很难弄清楚如何使用适当的模板化参数调用setValue函数。在ParameterBase抽象基类中不能有模板化的参数。任何帮助都是非常感谢的。

附言:我没有使用boost::any的灵活性。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-21 05:21:15

你就差那么一点了。我添加了一些内容,因为它们很方便

代码语言:javascript
运行
复制
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;
};

然后,图表可以执行以下操作:

代码语言:javascript
运行
复制
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

看起来你的意图是在向量中存储拥有资源的指针。如果是这样,请注意使Diagram具有正确的析构函数,并使其不可复制构造和不可复制赋值。

票数 35
EN

Stack Overflow用户

发布于 2012-12-21 05:02:46

下面的实现使用了一些C++11特性,但您将能够将它们分开。

代码语言:javascript
运行
复制
#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;
}

这段代码是做什么的?它隐藏了一个事实,即我们使用继承来实现对用户的参数。他们需要知道的是,我们需要一个名为foo的成员函数。这些需求在我们的ParameterBase中表达。您需要确定这些要求,并将添加到ParameterBase。这基本上是一个限制性更强的boost::any

它也非常接近Sean Parent's value semantics talk中所描述的内容。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13980157

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档