#include <iostream>
#include <tuple>

template<typename... Ts>
struct base
{
    std::tuple<Ts...> tuple;
};

template<typename... Ts>
struct deriv : base<Ts...>
{
};

//--------------------------------

template<typename T>
void func(const T&)
{
    std::cout << "T" << std::endl;
}

template<typename... Ts>
void func(const base<Ts...>&)
{
    std::cout << "base<Ts...>" << std::endl;
}

//----------------------------------------

int main()
{
    int a;
    base <int, double> b;
    deriv<int, double> c;

    func(a);
    func(b);
    func(static_cast<base<int, double> &>(c)); // <--- I want func<base<Ts...>> not func<T> to be called here

    exit(0);
}