来自"的修改代码使用enable_if"检查成员是否存在不管用

时间:2018-02-07 02:23:27

标签: c++ c++11 template-meta-programming sfinae

我读过这篇文章。 check if member exists using enable_if 我像这样修改了Johanness Schaub的代码。

//////////////////////////////////////////////////////////////////////////
struct NormalChecker {
    struct general_ {};
    struct special_ : general_ {};
    template<typename> struct int_ { typedef int type; };

    template<typename Lhs>
    void modify(Lhs &&lhs) {
        cout << "modify\r\n";
        modifyNormal(lhs, special_());
    }

    template<typename Lhs, typename int_<decltype(Lhs::normal)>::type = 0>
    void modifyNormal(Lhs &&lhs, special_) {
        cout << "modifyNormal with normal\r\n";
    }

    template<typename Lhs>
    void modifyNormal(Lhs &&lhs, general_) {
        cout << "modifyNormal without normal\r\n";
    }
};

struct DataWithNormal {
    int normal;
};

struct DataWithoutNormal {
};

int main() {
    DataWithNormal with_normal;
    DataWithoutNormal without_normal;

    NormalChecker normalCheckerWithNormal;
    normalCheckerWithNormal.modify(with_normal);
    NormalChecker normalCheckerWithoutNormal;
    normalCheckerWithoutNormal.modify(without_normal);

    return 0;
}

但是,它只是说&#34;在没有正常的情况下修改正常&#34;两次。 我错过了什么?

1 个答案:

答案 0 :(得分:3)

Lhs在您的示例中被推断为引用类型,特别是DataWithNormal&。引用类型没有嵌套的normal。解决此问题的一种方法是在剥离引用时检查Lhs

decltype(std::remove_reference<Lhs>::type::normal)

提升伊戈尔的评论,你也可以假装你有一个对象,因为访问一个对象的成员甚至可以使用一个引用:

decltype(std::declval<Lhs>().normal)