detecting protected constructors of (possibly abstract) base class

前端 未结 1 2000
无人共我
无人共我 2021-02-13 04:15

I am experimenting with the new features of C++11. In my setup I would really love to use inheriting constructors, but unfortunately no compiler implements those yet. Therefore

相关标签:
1条回答
  • 2021-02-13 04:49

    This appears to work fine on my local GCC (4.7, courtesy of rubenvb). GCC on ideone prints several "implemented" compiler internal errors though.

    I had to make the "implementation details" of the Experiment class public, because for some reasons (which smells like a bug), my version of GCC complains about them being private, even though only the class itself uses it.

    #include <utility>
    
    template<typename T, typename Ignored>
    struct Ignore { typedef T type; };
    
    struct EatAll {
      template<typename ...T>
      EatAll(T&&...) {}
    };
    
    template<typename T>
    struct Experiment : T {
    public:
      typedef char yes[1];
      typedef char no[2];
    
      static void check1(T const&);
      static void check1(EatAll);
    
      // if this SFINAE fails, T accepts it
      template<typename ...U>
      static auto check(int, U&&...u)
        -> typename Ignore<no&, 
            decltype(Experiment::check1({std::forward<U>(u)...}))>::type;
    
      template<typename ...U>
      static yes &check(long, U&&...);
    
    public:
      void f() {}
      template<typename ...U, 
               typename std::enable_if<
                 std::is_same<decltype(Experiment::check(0, std::declval<U>()...)),
                              yes&>::value, int>::type = 0>
      Experiment(U &&...u):T{ std::forward<U>(u)... }
      {}
    };
    
    // TEST
    
    struct AbstractBase {
      protected:
        AbstractBase(int, float);
        virtual void f() = 0;
    };
    
    struct Annoyer { Annoyer(int); };
    
    void x(Experiment<AbstractBase>);
    void x(Annoyer);
    
    int main() {
      x({42});
      x({42, 43.f});
    }
    

    Update: The code also works on Clang.

    0 讨论(0)
提交回复
热议问题