1

I'm trying to write a class that inherites std::vector, and holds my own data objects, like below:

#include<iostream>
#include<vector>
using namespace std;

template <class T>
class Data {
    T data;
public:
    void print() { cout << data << endl; }
};

template<class T>
class Container : public std::vector<Data<T>>
{
public:
    void f() {
        cout << data() << endl;
    }
};

int main() {
    Container<int> si;
    si.push_back(Data<int>());
    return 0;
}

It doesn't compile, gcc says:

<source>: In member function 'void Container<T>::f()':
<source>:17:21: error: no matching function for call to 'data()'
   17 |         cout << data() << endl;
      |                 ~~~~^~
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/string:52,
                 from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/locale_classes.h:40,
                 from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/ios_base.h:41,
                 from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ios:42,
                 from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ostream:38,
                 from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/iostream:39,
                 from <source>:1:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/range_access.h:311:5: note: candidate: 'template<class _Container> constexpr decltype (__cont.data()) std::data(_Container&)'
  311 |     data(_Container& __cont) noexcept(noexcept(__cont.data()))
      |     ^~~~

I fixed it as below:

template<class T>
class Container : public std::vector<Data<T>>
{
    using ContainerArray = std::vector<Data<T>>;
public:
    void f() {
        cout << ContainerArray::data() << endl;
    }
};

Now it compiles and works. But still, I think this fix is really ugly: why do I have to use XXX::data() everytime I call vector's function? As long as vector is father class, why I can't call it directly?

Does this relate to template class vector, or because I'm inheriting a template class from another template class? I made a quick test to use a normal class to inherit vector:

class Normal : public std::vector<Data<int>>
{
public:
    void f() {
        cout << data() << endl;
    }
};

This time it works, doesn't require that ugly prefix to get compiled. What's the c++ syntax reason behind this?

Thanks a lot!

Immanuel Kant
  • 517
  • 3
  • 8
  • 1
    [In a templated derived class, why do I need to qualify base class member names with "this->" inside a member function?](https://stackoverflow.com/questions/7908248/in-a-templated-derived-class-why-do-i-need-to-qualify-base-class-member-names-w) or [Derived template-class access to base-class member-data](https://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data) or [Why derived class template can't access base template member?](https://stackoverflow.com/questions/1239908/why-doesnt-a-derived-template-class-have-access-to-a-base-template-class-ident) – Jason Nov 02 '22 at 08:53

0 Answers0