【问题标题】:Incomplete type while accessing templated derived class (CRTP)' static function while doing SFINAE在执行 SFINAE 时访问模板派生类 (CRTP) 的静态函数时类型不完整
【发布时间】:2017-04-09 13:49:21
【问题描述】:

Demo

template <typename T>
struct A {
    void mem_func() {
        // This works!!! Can access static_func<int>();
        std::cout << T::template static_func<int>() << '\n';
    }
    template <typename K>
    static constexpr bool static_func() { return true; }

    template <typename T1>
    typename std::enable_if<T::template static_func<T1>(), void> sfinae_func() { 
        // This breaks!!! T is an incomplete type??
        std::cout << "This fails" <<'\n';
    }
};

struct B : A<B> {
};

在这里,我不明白为什么 T::static_func 在成员函数 foo() 中工作,但是当我去实例化 sfinae_func 时,相同的 T::static_func 是不可访问的,因为 T 不完整!这怎么可能?

后续是这样的: 如果标准限制我在 enable_if 中访问 T::static_func,是否有解决方法在需要时用 T::static_func 隐藏 A::static_funct?

template <typename T1>
    typename std::enable_if<T::template static_func<T1>(), void> sfinae_func()

如果调用 T 的 static_func 以使 T 的 static_func 隐藏 A 的 static_func 需要做什么来启用?

【问题讨论】:

    标签: c++ c++11 templates sfinae crtp


    【解决方案1】:

    要解决此问题,您可以通过将 T 的 sfinae_func 附加模板参数的默认值设置为默认值来延迟类型实例化,例如如下(哦,别忘了使用std::enable_if的内部类型来实际执行sfinae):

    #include <iostream>
    template <typename T>
    struct A {
        void mem_func() {
            std::cout << T::template static_func<int>() << '\n';
        }
        template <typename K>
        static constexpr bool static_func() { return true; }
    
        template <typename T1, typename TT = T>
        typename std::enable_if<TT::template static_func<T1>(), void>::type sfinae_func() {
            std::cout << "This fails" <<'\n';
        }
    };
    
    struct B : A<B> {
    };
    int main() {
        B a;
        a.mem_func();
        a.sfinae_func<int>();
    }
    

    [live demo]

    【讨论】:

    • 一般来说访问依赖类型成员的方法应该在实例化时访问。问题是 T 不是 sfinae_func 方法的依赖类型,因此编译器可能会认为它应该在创建时立即访问,并且当时 B 还没有从 A 继承 - 不完整(如编译器实际上建议)...
    • @them 主体在使用之前不会被实例化;即使不使用签名。
    猜你喜欢
    • 2023-03-20
    • 2016-05-27
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多