When inheriting a constructor template, GCC (6.2.0 via MinGW-w64, 6.3 via Ideone.com) seems to ignore access modifiers.
#include <iostream>
class Base
{
protected:
template<typename ...Args>
Base(Args ...args)
{
std::cout << "variadic ctor" << std::endl;
}
template<typename T>
Base(T t)
{
std::cout << "template ctor" << std::endl;
}
Base(char const *s)
{
std::cout << s << std::endl;
}
};
class Derived : public Base
{
protected:
using Base::Base;
};
int main(int, char**) noexcept
{
//Base bv{ 0, 1 }; // error: 'Base::Base(Args ...) [with Args = {int, int}]' is protected within this context
//Base bt{ 0 }; // error: 'Base::Base(T) [with T = int]' is protected within this context
//Base bs{ "base" }; // error: 'Base::Base(const char*)' is protected within this context
Derived dv{ 0, 1 };
Derived dt{ 0 };
//Derived ds{ "derived" }; // error: 'Derived::Derived(const char*)' is protected within this context
return 0;
}
None of these should be constructible, but the Derived class is still constructible through the templated constructors. As shown by the char const
constructor, only the non-template constructor inherits proper access modifiers.
This is incorrect behavior, isn't it?
EDIT: This answer provides the following related citation when using X::X;
:
A constructor so declared has the same access as the corresponding constructor in X.
From 12.9/4, "Inheriting constructors".