lundi 23 décembre 2019

Remove class member type part from decltype

I ran into I case I had not seen before, while using decltype on a member of a templated class. I wanted to make a nicer make_unique so that changing type on the member does not cause fixing the make_unique calls. I wanted to avoid this using decltype(member)::element_type as the type for make_unique but got an error. Here is a simple snippet that shows the error (and I understand why it is shown):

#include <memory>

template<typename T>
struct foo
{
    foo()
    {
        // g++ gives:
        //   dependent-name 'decltype (((foo<T>*)this)->foo<T>::p_)::element_type' is parsed as a non-type, but instantiation yields a type
        //   say 'typename decltype (((foo<T>*)this)->foo<T>::p_)::element_type' if a type is meant
        //
        // How can I atleast remove the class name from the type?
        p_ = std::make_unique<decltype(p_)::element_type>();
        // g++ gives:
        //  dependent-name 'decltype (p)::element_type' is parsed as a non-type, but instantiation yields a type
        //  say 'typename decltype (p)::element_type' if a type is meant
        //
        // makes sense since p here is dependent on T
        std::unique_ptr<T> p = std::make_unique<decltype(p)::element_type>();
        // This one is fine, makes sense, since the type is known
        std::unique_ptr<int> p2 = std::make_unique<decltype(p2)::element_type>();
    }
    std::unique_ptr<T> p_;
};

int main()
{
    foo<int> f;
    return 0;
}

My question is, is there a nice/pretty way to remove the 'is a member of' part from the decltype value, so that at least I could use the same fix and simply provide typename on the member variable p_ ? The long fix suggested by g++ seems kind of ugly.

Aucun commentaire:

Enregistrer un commentaire