首先,我有这样的事情:
class Test {
std::vector<int> a, b;
void caller(...) { callee(...); }
void callee(...) { /* Do stuff with 'a' */ }
}
我想要的是具有与callee
完全相同但对于向量b
的函数。要做到这一点,有两个明显的解决方案:
a
或b
作为参数。但是,callee
是一个递归函数,可以进行数百次调用,并将向量作为参数传递只是不必要的开销。callee
并使用向量b
,这将是最好的选择,尽管callee
是一个很长的函数,我会有很多重复的代码出于好奇,我去寻找模板部分,我发现可以用于
左值参考类型
指针类型
指向成员类型的指针
所以我试着这样做:
class Test {
std::vector<int> a, b;
void caller(...) { callee<a>(...); }
template <std::vector<int> &x> void callee(...) { /* Do stuff with 'x' */ }
}
但我得到
错误:在常量表达式中使用'this'
有没有办法用引用或指针实现这个?
顺便说一句,我想要的东西可以看作是函数范围的#define
答案 0 :(得分:7)
阵列甚至是元组,但是对成员的好老指点没有爱?
class Test {
std::vector<int> a, b;
void caller(/*...*/) { callee<&Test::a>(/*...*/); }
template <std::vector<int> Test::*vec>
void callee(/*...*/) { /* Do stuff with `(this->*vec)` */ }
};
答案 1 :(得分:4)
您不能将对数据成员的引用用作模板参数:模板是编译时的,并且在运行时之前不知道this
的值。换句话说,对于Test
类型的每个运行时对象,您需要单独的实例化(单独的二进制代码)。
可以做的是用数组替换a
和b
,并通过索引将callee
模板化到此数组中:
class Test {
std::array<std::vector<int>, 2> ab;
void caller(...) { callee<0>(...); }
template <size_t idx>
void callee(...) { /* Do stuff with 'ab[idx]' */ }
}
这样,您只获得callee
的一个实例化(一个用于0
,一个用于1
),编译时索引完成(或至少可行)。 / p>
答案 2 :(得分:2)
只需使用立面:
class Test {
std::vector<int> a, b;
void caller_a(...) { callee(a); }
void caller_b(...) { callee(b); }
void callee(std::vector<int> &a_or_b, ...) {
}
}
callee()
将引用其参数,该参数将作为一个或另一个类成员传递。
答案 3 :(得分:1)
与@Angew的回答相同,你也可以使用std :: tuple,它非常有趣,因为你可以在你的被调用函数中使用不同类型的容器:< / p>
class Test {
std::tuple<std::vector<int>, std::list<int> > ab;
void caller(...) { callee<0>(...); }
template <size_t idx>
void callee(...) {
...
auto aIt = std::get<idx>(ab).begin(); // gets either the vector or the list depending on template value
...
}
}