假设您有以下课程:
class Data
{
public:
int a;
int b;
};
class DataOther
{
public:
int a;
int b;
};
class Line
{
public:
Data Right;
Data Left;
};
class LineOther
{
public:
DataOther Right;
DataOther Left;
}
我有很多以这种方式构建的类,当我想在数据的两个边上运行代码时,我通常会这样做:
enum class Side { RIGHT, LEFT };
template<typename T>
auto GetBySide(const Side &side, T &data) -> decltype(data.Right) &
{
return side == Side::Left ? data.Left : data.Right;
}
然后在代码中:
Line l;
LineOther lOther;
for(auto &side: {Sides::LEFT, Sides::Right})
{
auto &d = GetBySide(side, l);
auto &dOther = GetBySide(side, lOther);
// Do some stuff with the data
}
现在这个问题的缺点是,它是运行时所以不能进行太多优化,尽管我认为编译器可能会展开循环。
关于如何构建代码的任何其他想法?
答案 0 :(得分:0)
如果您担心展开,可以替换:
Line l;
LineOther lOther;
for (auto &side: {Sides::LEFT, Sides::Right})
{
auto &d = GetBySide(side, l);
auto &dOther = GetBySide(side, lOther);
// Do some stuff with the data
}
通过以下方式:
template <Side side>
void foo(Line& l, LineOther& lOther) {
auto &d = GetBySide(side, l);
auto &dOther = GetBySide(side, lOther);
// Do some stuff with the data
}
和
Line l;
LineOther lOther;
foo<Sides::LEFT>(l, lOther);
foo<Sides::Right>(l, lOther);
答案 1 :(得分:0)
&#34;我有很多以这种方式构建的课程&#34;似乎你只能留下其中一个。或者至少利用继承或其他技术来避免重复:
// Declare base class instead of copypasting fields.
class BaseLine
{
public:
int Right{};
int Left{};
};
class Line: public BaseLine
{};
class LineOther: public BaseLine
{};
int main()
{
Line l;
l.Right = 45; l.Left = 89;
LineOther lOther;
lOther.Right = 74; lOther.Left = 33;
// Use pointer to member to iterate over fields.
for(auto p_side: {&BaseLine::Right, &BaseLine::Left})
{
::std::cout << (l.*p_side) << ::std::endl;
::std::cout << (lOther.*p_side) << ::std::endl;
}
}