東西沿着這些路線。
請注意,現在我可以添加新的點類型(或設置類型),而不必在多個函數中更改邏輯。我所要做的就是爲新類型提供ADL過載operator>>
和do_something
。
因此,我的核心邏輯現在與每個集合類型/點類型的實現細節分開。如果我想在其他座標系統中使用相同的代碼點,我就不需要更改代碼(在實際項目中)。
#include <iostream>
#include <vector>
struct pt {
double t;
double e;
double c_vis;
double c_invis;
};
std::istream& operator>>(std::istream& is, pt& p)
{
p.c_vis = 0;
p.c_invis = 0;
return is >> p.t >> p.e;
}
struct pt_weighted : pt {
double sigma;
};
std::istream& operator>>(std::istream& is, pt_weighted& p)
{
auto sigma_correction = [](double& sigma) {
// whatever this is supposed to do;
};
is >> static_cast<pt&>(p) >> p.sigma;
sigma_correction(p.e);
return is;
}
template<class Point> struct set
{
using point_type = Point; // the type name point_type is now part of the set's type interface, so I can use it in dependent code.
std::vector<point_type> points;
};
using pt_set = set<pt>;
using pt_weighted_set = set<pt_weighted>;
//
// one implementation of read logic, for all set types.
//
template<class SetType>
void read_set(std::istream& is, SetType& target)
{
while(is) {
// using the type protocol here
auto point = typename SetType::point_type(); // or target.makePoint() ?
is >> point;
target.points.push_back(std::move(point));
}
}
extern void do_something(pt_set&);
extern void do_something(pt_weighted_set&);
void operation(std::istream& is)
{
extern bool useSigma();
// even these lines now no longer need to be repeated
auto perform = [](auto&& myset) {
read_set(is, myset);
do_something(myset);
};
if (useSigma())
{
perform(pt_weighted_set());
}
//else if (someOtherCondition()) {
// perform(someOtherSetType());
//}
else {
perform(pt_set());
}
};