2

Here is a piece of code which fails to compile under g++-7.2 and clang-5.0 and compiles perfectly under g++-5 (-std=c++11).

#include <vector>

template<typename T>
class Array : private std::vector<T> {
public:
    typedef std::vector<T> Base;

    using Base::Base;
};

int main() {
    Array<int> a((int*)nullptr, (int*)nullptr);
}

The error arises at the linking stage: main.cpp:(.text+0x11): undefined reference to 'std::allocator<int>::allocator()'.

If I declare my array as Array<int> a, it compiles perfectly.

What's the problem here? As far as I understand, instantiation of template Array<int> enforces instantiation of std::vector<int>, which, in order, instantiates std::allocator<int>.

Demo with g++-5

Demo with g++-7

P.S. I'm aware of possible pitfalls in inheriting from STL containers. Here inheritance is private, and this answer claims that it is allowed. Anyway, the question is not about whether it is a good practice or not.

P.P.S. I would be glad if you suggest a better title.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
Ivan Smirnov
  • 4,365
  • 19
  • 30
  • 1
    "In my case there are no additional data members, so it should not pose any problems." - wrong thinking. –  Oct 26 '17 at 21:34
  • 2
    OK, you're right, I'll make the inheritance private. This answer claims that it is allowed: https://stackoverflow.com/a/4357417/2159939. It still does not remove the error, and my question is NOT about inheriting from STL containers by itself. – Ivan Smirnov Oct 26 '17 at 21:37
  • 2
    Seems like a compiler bug to me – M.M Oct 26 '17 at 21:54
  • And what should happen (if it would compile) when you pass two nullptr? –  Oct 26 '17 at 22:21
  • 1
    @manni66 I don't care about what happens at runtime, I just wanted to call a constructor from two int pointers (which exists), and passing nullptr-s is the simplest way to do it. It is a minimal example, not real code. – Ivan Smirnov Oct 26 '17 at 22:23
  • This compiles and links on g++ (GCC) 5.4.0 and Apple LLVM version 9.0.0 (clang-900.0.38) Command line : g++ --std=c++14 -Wall -g main.cc – natersoz Oct 26 '17 at 23:42

1 Answers1

1

There was a change on semantics of inherited constructors in GCC7. However, you can compile your code using -fno-new-inheriting-ctors switch.

More information is in GCC7 changelog: https://gcc.gnu.org/gcc-7/changes.html and P0136.

pe3k
  • 796
  • 5
  • 15