请考虑以下代码:
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
virtual ~A() {
}
};
class B : public A {
};
void foo(A& a) {
cout << "A&" << endl;
}
void foo(const A& a) {
cout << "const A&" << endl;
}
void foo(A* a) {
cout << "A*" << endl;
}
void foo(const A* a) {
cout << "const A*" << endl;
}
template <class T>
void foo(T& a) {
cout << "T&" << endl;
}
template <class T>
void foo(const T& a) {
cout << "const T&" << endl;
}
template <class T>
void foo(T* a) {
cout << "T*" << endl;
}
template <class T>
void foo(const T* a) {
cout << "const T*" << endl;
}
int main(int argc, char** argv) {
B a;
foo(a);
B& b = a;
foo(b);
B* c = &a;
foo(c);
const B& d = a;
foo(d);
const B* e = &a;
foo(e);
return EXIT_SUCCESS;
}
产生以下输出:
T&
T&
T*
const T&
const T*
这个输出让我感到惊讶,因为我认为最接近匹配的函数是被调用的函数。所以我期待输出:
A&
A&
A*
const A&
const A*
当我传入基类(A)的子类(B)时,是否可以解释为什么在基类重载时选择模板函数重载?
答案 0 :(得分:5)
这是预期的行为。致电foo(a);
a
时,B
为B
。因此,我们需要从A
到void foo(A& a)
的隐式转换才能调用template <class T>
void foo(T& a) {
cout << "T&" << endl;
}
。但是,因为你也有
void foo(B& a)
模板被盖章,你得到T
。这是直接匹配,无需转换。这是最好的功能,这就是它被选中的原因。这对于所有其他函数都是相同的,并且B
被推导到A
,这提供了与所有#initializations
mydata$Sum.W.Type1 <- 0
mydata$Sum.W.Type2 <- 0
mydata$Sum.W.Type6 <- 0
#assignment
mydata[,5:7] <-
sapply(c(1, 2, 6), function(y)
apply(mydata, 1,
function(x, TYPE = y)
sum(ifelse(mydata[mydata$ID == x[1] & mydata$TYPE == TYPE,]$HEIGHT > x[3],
mydata[mydata$ID == x[1] & mydata$TYPE == TYPE,]$WEIGHT, 0))))
mydata
ID TYPE HEIGHT WEIGHT Sum.W.Type1 Sum.W.Type2 Sum.W.Type6
1 20 6 194 77.1 0.0 0.0 59.6
2 20 2 175 63.5 74.3 0.0 136.7
3 20 6 197 59.6 0.0 0.0 0.0
4 20 1 185 74.3 0.0 0.0 136.7
5 20 1 162 94.4 74.3 63.5 136.7
6 21 1 188 58.9 0.0 0.0 0.0
7 21 6 182 81.2 58.9 0.0 0.0
8 21 6 169 82.8 58.9 0.0 81.2
9 21 2 151 78.5 58.9 0.0 164.0
函数更好的匹配。
如果您想停止此操作,可以使用std::enable_if
并检查该类型是否为std::is_base_of
的派生类