md-blog icon indicating copy to clipboard operation
md-blog copied to clipboard

当private继承时还是会有问题。

Open condy0919 opened this issue 9 years ago • 3 comments

https://github.com/lexdene/md-blog/blob/master/cpp/is_derived_from/is_derived_from.md 在上面链接中,单例模式下仍有问题。 不如学/分析一下 is_base_of。

template <typename B, typename D>
struct Host {
    operator B*() const;
    operator D*();
};

template <typename B, typename D>
struct is_base_of {
private:
    typedef char (&yes)[1];
    typedef char (&no)[2];

    template <typename T>
    static yes check(D*, T);
    static no check(B*, int);

public:
    static const bool value = sizeof(check(Host<B, D>(), int())) == sizeof(yes);
};

struct Base {};
struct Derived : private Base {};

int main() {
    static_assert(is_base_of<Base, Derived>::value, "Error");
    is_base_of<Derived, Base>::value;
}

condy0919 avatar Mar 08 '15 06:03 condy0919

没说清楚,如果有

struct foo {};
struct bar : private foo {};
ConvertTester3<foo, bar>::test;

会编译出错。如果test为false的话,感觉会更好。

condy0919 avatar Mar 08 '15 06:03 condy0919

学习了。

不过能否解释一下,check函数为什么要有2个参数?我刚试了一下,发现把第2个参数删掉就不对了,但是不太明白为什么。

lexdene avatar Mar 09 '15 04:03 lexdene

可以看一下这个。 http://stackoverflow.com/questions/2910979/how-does-is-base-of-work 第1个函数必须是模板,否则在2个类没有关系时会出现二义性。成为模板后,当发现有其他非模板函数可以匹配时,不考虑模板的版本,因而在这种情况下运行正确。 当2个类有关系时,由函数拾取规则得到会同时使用operator D*()这个转换函数,再由D类型更匹配static yes check(D, T);因而得到。如果没有第2个参数而又是模板的情况下,会因为无法推导出T类型而直接会被从candidates中去除,从而只能匹配第2个函数,根据条款4.10/3得到error.

condy0919 avatar Mar 11 '15 05:03 condy0919