访问函数的调用者类型

时间:2018-02-24 18:41:40

标签: c++

现在,我知道这个问题多次出现,例如here。但是,对于初学者来说,回答这个问题只是“不要使用它,这是糟糕的编程”,我认为这是我用例中的最佳解决方案。

但是要点:我想在C ++中访问函数调用者的类型。 Tldr,我想在typeid(CALLER)中使用它。下面是关于我的用例的详细信息

我有一个对象,我们称之为AnalyzedObject,这是多个(多态)Evaluator的评估主题,无论是被接受还是被拒绝。总而言之,我希望AnalyzedObject本身知道它是被接受还是被拒绝,但问题是Evaluator s'的投票不是直接计算的,而是Evaluator}的影响。取决于它的类型。所以,我有一些或多或少的东西:

struct AnalyzedObject {
  unordered_map<type_index, bool> votes;
  bool accepted;
  // other data...

  void add_vote(bool vote) {
    votes[????]=vote;
  }
}

class Evaluator {
  void Evaluate(AnalyzedObject& obj) {
    obj.add_vote(vote());
  }

  virtual void vote() = 0;
}

class VotingPolicy {
  bool Elect(unordered_map<type_index, bool> votes);
}

AnalyzedObject object;
vector<Evaluator*> evaluators;
for(auto evaluator : evaluators) {
  evaluator->Evaluate(object);
}
VotingPolicy policy;
object.accepted = policy.Elect(object.votes);

所以,问题是:我应该如何填写问号(????),以便在这里完成工作?

我知道,我可以做一些变通办法,例如

void add_vote(Evaluator& type, bool vote) {
  votes[typeid(decltype(evaluator))]=vote;
}

template<class T>
void add_vote(bool vote) {
  votes[typeid(T)]=vote;
}

但要对API正确性迂腐,那么参数总是this,因此应该省略......

无论如何,如果您碰巧有任何其他想法如何解决我的问题,请随意提出不同的建议!

1 个答案:

答案 0 :(得分:0)

以下是投票政策的一个示例,该投票政策收集选民的集合并对某些对象返回是/否投票。我认为这个例子很好地将逻辑放在函数中,并传递每个函数所需的内容。

#include <vector>

// abstract base class (interface) for AnalyzedObject
class AnalyzedObject {
public:
    AnalyzedObject() {}
    virtual ~AnalyzedObject() {}

    // provide getters for all the things an evaluator may consider
    virtual bool Do_you_support_key_feature_one() const = 0;
    virtual bool Do_you_support_key_feature_two() const = 0;
    virtual int YearsService() const = 0;
    virtual int Price() const = 0;
};

// abstract base class (interface) for voter/evaluator
class Evaluator {
public:
    Evaluator();
    virtual ~Evaluator() {}
    virtual bool vote(const AnalyzedObject&) = 0;
};

// raw pointers here is ill-advised
typedef std::vector<Evaluator*> voter_panel_type;

// abstract base class (interface) for voting policy
class VotingPolicy {
public:
    VotingPolicy();
    virtual ~VotingPolicy() {}
    virtual bool vote(voter_panel_type, const AnalyzedObject&) = 0;
};

// implement a voting policy
class MajorityRules : public VotingPolicy {
    bool vote(std::vector<Evaluator*> evaluators, const AnalyzedObject &object) {
        voter_panel_type::size_type yes = 0;
        for (auto voter : evaluators) {
            if (voter->vote(object))
                yes += 1;
        }
        return yes * 2 > evaluators.size();
    }
};