如何指示容器中的多态仿函数完成其工作和 return 结果?
How to instruct a polymorphic functor in a container to do its job and return results?
我有一个 std::vector<>
指向基函子的指针。这个容器,一个计算器class,应该能够保存任意数量的计算任意统计数据的函数对象。
我正在努力解决的部分是如何为容器编写一个方法 class,迭代这些指针,从 hte 组中选择您感兴趣的那个,告诉它做它的工作是调用 operator()
,然后 returns 结果。
这里有一些代码可以说明这个想法:
#include <iostream>
#include <memory> //shared_ptr
#include <vector>
class BaseFunctor{
virtual double operator()(std::vector<double> inputs) = 0;
};
class Sum : public BaseFunctor{
double operator() (std::vector<double> inputs){
double sum (0.0);
for(auto elem : inputs)
sum += elem;
return sum;
}
};
class Prod : public BaseFunctor{
double operator() (std::vector<double> inputs){
double sum (1.0);
for(auto elem : inputs)
sum *= elem;
return sum;
}
};
class Calculator {
private:
std::vector<std::shared_ptr<BaseFunctor>> m_stats;
std::vector<double> m_simple_data;
public:
Calculator()
: m_simple_data({1.0, 2.0, 3.0}) {};
void addStat(std::shared_ptr<BaseFunctor> stat) {
m_stats.push_back(stat);
}
// calculate stat?
};
int main() {
Calculator calc;
calc.addStat(std::make_shared<Sum>());
calc.addStat(std::make_shared<Prod>());
return 0;
}
现在,我如何告诉 calc
给我产品,而且只给我产品?尤其是当我无法控制用户最终对哪些统计数据感兴趣时?
我想我可以将指针存储在 map
中,但这似乎是多余的:使密钥与 class.
同名
Here 是一个想法,但无法编译。
这可行,但我愿意 comments/criticisms/suggestions。
#include <iostream>
#include <memory> //unique_ptr
#include <map>
#include <vector>
#include <string>
#include <functional>
class BaseFunctor{
public:
virtual double operator()(std::vector<double> inputs) = 0;
virtual std::string name() = 0;
};
class Sum : public BaseFunctor{
double operator() (std::vector<double> inputs){
double sum (0.0);
for(auto elem : inputs)
sum += elem;
return sum;
}
std::string name() { return "sum"; }
};
class Prod : public BaseFunctor{
double operator() (std::vector<double> inputs){
double prod (1.0);
for(auto elem : inputs)
prod *= elem;
return prod;
}
std::string name() { return "prod"; }
};
class Calculator {
private:
std::map<std::string, std::unique_ptr<BaseFunctor> > m_stats;
std::vector<double> m_simple_data;
public:
Calculator()
: m_simple_data({1.0, 2.0, 5.0}) {};
void addStat(std::unique_ptr<BaseFunctor> stat) {
m_stats.insert(
std::pair<std::string, std::unique_ptr<BaseFunctor>>(
stat->name(),
std::move(stat)
)
);
//m_stats.push_back(std::move(stat));
}
double calc(std::string op_name){
return (*m_stats[op_name])(m_simple_data);
}
};
int main() {
Calculator thing;
thing.addStat(std::unique_ptr<BaseFunctor>(new Sum()) );
thing.addStat(std::unique_ptr<BaseFunctor>(new Prod()) );
std::cout << "sum: " << thing.calc("sum") << "\n";
std::cout << "prod: " << thing.calc("prod");
return 0;
}
我有一个 std::vector<>
指向基函子的指针。这个容器,一个计算器class,应该能够保存任意数量的计算任意统计数据的函数对象。
我正在努力解决的部分是如何为容器编写一个方法 class,迭代这些指针,从 hte 组中选择您感兴趣的那个,告诉它做它的工作是调用 operator()
,然后 returns 结果。
这里有一些代码可以说明这个想法:
#include <iostream>
#include <memory> //shared_ptr
#include <vector>
class BaseFunctor{
virtual double operator()(std::vector<double> inputs) = 0;
};
class Sum : public BaseFunctor{
double operator() (std::vector<double> inputs){
double sum (0.0);
for(auto elem : inputs)
sum += elem;
return sum;
}
};
class Prod : public BaseFunctor{
double operator() (std::vector<double> inputs){
double sum (1.0);
for(auto elem : inputs)
sum *= elem;
return sum;
}
};
class Calculator {
private:
std::vector<std::shared_ptr<BaseFunctor>> m_stats;
std::vector<double> m_simple_data;
public:
Calculator()
: m_simple_data({1.0, 2.0, 3.0}) {};
void addStat(std::shared_ptr<BaseFunctor> stat) {
m_stats.push_back(stat);
}
// calculate stat?
};
int main() {
Calculator calc;
calc.addStat(std::make_shared<Sum>());
calc.addStat(std::make_shared<Prod>());
return 0;
}
现在,我如何告诉 calc
给我产品,而且只给我产品?尤其是当我无法控制用户最终对哪些统计数据感兴趣时?
我想我可以将指针存储在 map
中,但这似乎是多余的:使密钥与 class.
Here 是一个想法,但无法编译。
这可行,但我愿意 comments/criticisms/suggestions。
#include <iostream>
#include <memory> //unique_ptr
#include <map>
#include <vector>
#include <string>
#include <functional>
class BaseFunctor{
public:
virtual double operator()(std::vector<double> inputs) = 0;
virtual std::string name() = 0;
};
class Sum : public BaseFunctor{
double operator() (std::vector<double> inputs){
double sum (0.0);
for(auto elem : inputs)
sum += elem;
return sum;
}
std::string name() { return "sum"; }
};
class Prod : public BaseFunctor{
double operator() (std::vector<double> inputs){
double prod (1.0);
for(auto elem : inputs)
prod *= elem;
return prod;
}
std::string name() { return "prod"; }
};
class Calculator {
private:
std::map<std::string, std::unique_ptr<BaseFunctor> > m_stats;
std::vector<double> m_simple_data;
public:
Calculator()
: m_simple_data({1.0, 2.0, 5.0}) {};
void addStat(std::unique_ptr<BaseFunctor> stat) {
m_stats.insert(
std::pair<std::string, std::unique_ptr<BaseFunctor>>(
stat->name(),
std::move(stat)
)
);
//m_stats.push_back(std::move(stat));
}
double calc(std::string op_name){
return (*m_stats[op_name])(m_simple_data);
}
};
int main() {
Calculator thing;
thing.addStat(std::unique_ptr<BaseFunctor>(new Sum()) );
thing.addStat(std::unique_ptr<BaseFunctor>(new Prod()) );
std::cout << "sum: " << thing.calc("sum") << "\n";
std::cout << "prod: " << thing.calc("prod");
return 0;
}