我想用不同的参数列表重载一个函数。
例如,声明如下:
void processGraph(const std::vector<int>& vertexData)
void processGraph(const std::vector<int>& vertexData, const std::vector<int>& edgeData)
在应用程序中,有些图表有边缘数据,有些则没有。
此函数将迭代顶点和边缘数据。
for (int i = 0; i < vnum; ++i) {
for (int j = idx[i]; j < idx[i+1]; ++j) {
int dst = edge[j]
vertexData[i] = vertexData[i] + 1; // update vertex
edgeData[j] = edgeData[j] + 1; // update edge
}
}
我必须在两个函数中复制代码,它们只在一行中有所不同 - 更新边缘线。
目前我正在使用宏来避免重复。
我不会重载该功能。
void processGraph(const std::vector<int>& vertexData
#ifdef PROCESSEDGE
, const std::vector<int>& edgeData
#endif
)
在定义中
// inside some for loop
vertexData[i] = j; // update vertex
#ifdef PROCESSEDGE
edgeData[k] = l; // update edge
#endif
对于不同的配置,我添加了PROCESSEDGE
宏。
很明显,这没有开销。但它并不优雅。
我想到的另一个想法是在c ++ 11中使用一些编译时条件。
声明如下所示
void processGraph(const std::vector<int>& vertexData, const std::vector<EdgeType>& edgeData)
实施
// inside some for loop
vertexData[i] = j; // update vertex
if (!std::is_same<Empty, EdgeData>::value)
edgeData[k] = l; // update edge
因为在编译时评估条件,所以它应该没有运行时开销。但就我而言,if语句也不优雅。
优雅地做到这一点的最佳做法是什么?
[更新]我希望一切都是静态完成的。
答案 0 :(得分:0)
选项1:提供伪造的边缘数据,您委派的实施可以随意涂抹,然后将其放在地板上。这增加了一些内存需求,但循环中的赋值很简单,循环中没有添加分支。
void processGraph(const std::vector<int>& vertexData) {
std::vector<int> dummyEdgeData;
dummyEdgeData.resize(/* some appropriate value */);
processGraph(vetexData, dummyEdgeData);
}
void processGraph(const std::vector<int>& vertexData, const std::vector<int>& edgeData) {
// inside some for loop
vertexData[i] = j; // update vertex
edgeData[k] = l; // update edge
}
选项2:如果没有边缘数据,请相信循环内的分支将被很好地预测。
选项3:使用仿函数(如lambda)处理分配并提供“正确”分配,就像std::for_each
允许您提供循环体一样。
template <typename Functor>
void processGraphLoop(Functor f) {
// inside some for loop
f(i, j, k, l);
}
void processGraph(const std::vector<int>& vertexData) {
processGraphLoop([&](int i, int j, int k, int l) {
vertexData[i] = j;
});
}
void processGraph(const std::vector<int>& vertexData, const std::vector<int>& edgeData) {
processGraphLoop([&](int i, int j, int k, int l) {
vertexData[i] = j;
edgeData[k] = l;
});
}