I have an abstract base class, and a class which implement it in a very basic way:
class base {
public:
virtual ~base() = default;
virtual void func() = 0;
}
class base_core : public base {
public:
base_core(int);
void func() override {}
}
template <typename T>
concept IsBaseCore = std::is_base_of_v<base_core, T>;
Now, I crated a variadic inheritance and noticed a strange behavior, which I believe is wrong:
class temp_inheritance {};
template <typename Base, typename ...Decorators>
struct base_if_not_exists {
static constexpr bool value = sizeof...(Decorators);
using type = typename std::conditional_t<value, temp_inheritance, Base>;
};
template <typename T, IsBaseCore ...Cores>
class base_impl : virtual public base_if_not_exists<base_core, Cores...>::type, virtual public Cores... {
public:
base_impl() : Cores(5)... {
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::cout << "base_impl: Default CTOR" << std::endl;
}
base_impl(int num) : Cores(num)... {
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::cout << "base_impl: Non default CTOR" << std::endl;
}
void func() override { std::cout << "base_impl::func(): " << param << std::endl; }
private:
T param;
};
template <IsBaseCore ...Cores>
using impl_1 = base_impl<int, Cores...>;
template <IsBaseCore ...Cores>
using impl_2 = base_impl<double, Cores...>;
template <IsBaseCore ...Cores>
using impl_3 = base_impl<size_t, impl_1<impl_2<>>>;
int main() {
impl_3<> impl(5);
return EXIT_SUCCESS;
}
For some reason this output the following result:
base_core: Default CTOR
base_impl<T, Cores>::base_impl() [with T = double; Cores = {}]
base_impl: Default CTOR
base_impl<T, Cores>::base_impl(int) [with T = int; Cores = {base_impl<double>}]
base_impl: Non default CTOR
base_impl<T, Cores>::base_impl(int) [with T = long unsigned int; Cores = {base_impl<int, base_impl<double> >}]
base_impl: Non default CTOR
I have two points which are unclear to me in this output:
- Why there is a call for base_core default constructor?
- Why does the parametrize constructor of impl_2 is never called?
I am using Ubuntu 16.04 (tested on 20.04 too), GCC 10.2.