使用子类

时间:2016-08-19 16:48:42

标签: c++

请考虑以下代码:

#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)时,是否可以解释为什么在基类重载时选择模板函数重载?

1 个答案:

答案 0 :(得分:5)

这是预期的行为。致电foo(a); a时,BB。因此,我们需要从Avoid 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的派生类