Доступ к статическим данным через наследование параметра шаблона шаблона? - PullRequest
0 голосов
/ 01 ноября 2018
template
<
    template <typename, typename>
        class storage_t,
    typename T,
    typename is_allocated
>
class Buffer : public storage_t<T, is_allocated> { ... };

template
<
    template <typename, typename>
        class storage_t,
    typename T = storage::UnknownType,
    typename is_allocated = std::false_type
>
class Example_Buffer
: public Buffer<storage_t, T, is_allocated> {
    constexpr Example_Buffer(
        typename storage_t<T, is_allocated>::iterator it) {}
};

Example_Buffer<...> наследуется от Buffer<...>. Buffer<storage_t, T, is_allocated> наследуется от storage_t<T, is_allocated>. storage_t<...> включает typedefs и статические данные constexpr. Есть ли способ получить доступ к этим typedefs и static constexpr data в конструкторе Example_Buffer через наследование? (через наследование, то есть без использования storage_t<T, is_allocated>? Это немного странно использовать этот синтаксис дважды в одном и том же классе.

Не стесняйтесь спрашивать, нужно ли мне уточнить.

1 Ответ

0 голосов
/ 01 ноября 2018

Члены наследуются и доступны, если они являются открытыми в storage_t. Вы можете использовать имя внедренного класса и / или имя внедренного базового класса для доступа к этим зависимым членам,

Вот несколько вариантов ..

#include <iostream>
#include <type_traits>
#include <typeinfo>

using namespace std;

template <typename A,typename B>
struct basic_storage
{
    using a_type = A;
    using b_type = B;
    static constexpr bool value = b_type::value;
};


template
<
    template <typename, typename>
        class storage_t,
    typename T,
    typename is_allocated
>
class Buffer : public storage_t<T, is_allocated> {

    public:
    using storage_type = storage_t<T, is_allocated>;
};

template
<
    template <typename, typename>
        class storage_t,
    typename T /*= storage::UnknownType*/,
    typename is_allocated = std::false_type
>
class Example_Buffer
: public Buffer<storage_t, T, is_allocated> {
    public:
    constexpr Example_Buffer(
        /*typename storage_t<T, is_allocated>::iterator it*/) {

            //using the members with the injected class name..
            using b_type = typename Example_Buffer::b_type;

            // or directly using injected class name..
            std::cout << typeid(typename Example_Buffer::a_type).name() << std::endl;
            std::cout << Example_Buffer::value << std::endl;

            // using storage_type defined in Buffer<...>
            using storage_type = typename Example_Buffer::storage_type;

            std::cout << typeid(typename storage_type::a_type).name() << std::endl;
            std::cout << storage_type::b_type::value << std::endl;
            std::cout << storage_type::value << std::endl;

        }
};


int main() {
    Example_Buffer<basic_storage,int,std::true_type>{};
    return 0;
}

Демо

Если вам интересно, почему вы не можете просто получить доступ, то в производном классе, не добавляя к ним префикса Example_Buffer:: имя базового класса, как в этом посте объясняет, что это потому, что они являются зависимыми именами.

...