2

I was studying policy based design and created myself a contrived example.

#include <iostream>
#include <string>

template <typename T>
struct NewAllocator
{
    T* Allocate(){
        std::cout << "Allocated with new\n";
        return nullptr;
    }
};

template <typename T>
struct MallocAllocator
{
    T* Allocate(){
        std::cout << "Allocated with malloc\n";
        return nullptr;
    }
};

template <typename T>
struct CustomAllocator
{
    CustomAllocator(const char* name)
        :alloctr_name{name}
    {}

    T* Allocate(){
        std::cout << "Allocated with custom\n";
        return nullptr;
    }

    // Enriched behaviour
    void print_name()
    {
        std::cout << "Name of the allocator is: " << alloctr_name;
    }

    std::string alloctr_name;
};

template <typename T, template <typename Allocated> typename AllocationPolicy = NewAllocator>
struct my_container : public AllocationPolicy<T>
{
    my_container()
    :begin{AllocationPolicy<T>::Allocate()}
    {}

    // Host can use enriched behaviour from policies
    my_container(const char* alloctr_name)
    :AllocationPolicy<T>(alloctr_name)
    ,begin{AllocationPolicy<T>::Allocate()}
    {}

    // template only initialized if used
    void print_allocator_name()
    {
        AllocationPolicy<T>::print_name();
    }

    T *begin;
};

This works as intended but I am curious about something. In the first constructor of my_container, I call the Allocate method of the policy class to initialize the member as begin{AllocationPolicy<T>::Allocate()} and as I said things work. But if I try to do begin{Allocate()} at the same line, I get an error saying Allocate is an undeclared identifier. Why is this so? This is not a virtual function or anything. Allocate is a member function from my base class, shouldn't it be accessible to me without any qualification?

meguli
  • 1,426
  • 1
  • 18
  • 35
  • 3
    Because it is a dependent (on template parameter) name. Compiler is not aware of `Allocate` existence in a base class before you instantiate particular template variant. So writing base class name explicitly lets compiler figure out where `Allocate` comes from when this template is parsed. – user7860670 Apr 04 '18 at 08:02
  • VS scores here again, if you used it you wouldn't get this error! – Yola Apr 04 '18 at 08:12
  • @Yola Only if you don't specify [`/permissive-`](https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance). – cpplearner Apr 04 '18 at 09:19

0 Answers0