Curiously recurring problems with a subclass depending on template options and template

I am trying to do the following code work

template < class __derived, class __object = typename __derived::Object >
struct Base {
    using Derived = __derived;
    using Object = __object;
    void function(Object o) { return Derived::function(s); }
}

//template < class __derived >
//struct Base {
//    using Derived = __derived;
//    using Object = typename Derived::Object;
//    void function(Object o) { return Derived::function(s); }
//}

template < class __object >
struct Derived : public Base< Derived< __Object > > {
    using Object = __object;
    void function(Object o) { ... }
}

And I create an object by declaring

Derived<double> obj;

The problem is that the compiler claims that it cannot find the character Objectinside the class Derivedby displaying the second template parameter for the class Base. The same error is also generated by comments.

I am trying to do this under the inspiration of Eigen3 code, especially CRTP (Curiously Recurring Template Pattern), which they use to avoid using virtual functions. Eigen3 actually uses the class traits, but I cannot figure out how to mimic this for this case. Anyone have any suggestions on this? Thanks in advance!

+4
1

, , A B, B A, :

template < class __object >
struct Derived;

, , :

template<class __derived>
struct Base_traits {
    //using Object = ?????;
};
template<class __object>
struct Base_traits<Derived<__object>> {
    using Object = __object; //note, this also can't inspect B.
};

Base Base_traits , , B.

template < class __derived, class __object = typename Base_traits<__derived>::Object >
struct Base {
    using Derived = __derived;
    using Object = typename Base_traits<__derived>::Object;
    //or        
    using Object = __object;


, , , . .

,

void function(Object o) { return Derived::function(s); }

, upcasts, downcasts. Ergo, static_cast this. , :

    void foo(Object o) { self()->bar(o); }
private:
    __derived* self() {return static_cast<__derived*>(this);}
    const __derived* self() const {return static_cast<__derived*>(this);}
};

: http://coliru.stacked-crooked.com/a/81595b0fcd36ab93

+4

Source: https://habr.com/ru/post/1545002/


All Articles