Why does template argument deduction/substitution fail with std::tuple and template derived classes?

Viewed 1056

In the next code, the template argument deduction fails when I try to pass a std::tuple of reference derived classes as argument to the function that receive a std::tuple of reference base classes. Why the compiler can not be deduced the template arguments T1 and T2? and How can I fix it?

// Example program
#include <iostream>
#include <tuple>

template<typename T>
struct Base {};

template<typename T>
struct Derived1 : Base<T> {};

template<typename T>
struct Derived2 : Base<T> {};

template<typename T1, typename T2>
void function(std::tuple<Base<T1>&,Base<T2>&> arg)
{
    std::cout << "Hello\n";
}

int main()
{
    Derived1<int> d1;
    Derived2<double> d2;

    //function(std::tie(d1, d2));  /* In this case the template argument deduction/substitution failed */
    function<int,double>(std::tie(d1, d2)); /* here works */

    Base<int>& b1 = d1;
    Base<double>& b2 = d2;

    function(std::tie(b1, b2)); /* but, in this case also works */
}

This is the compile error for the line code function(std::tie(d1, d2));:

 In function 'int main()':
25:30: error: no matching function for call to 'function(std::tuple<Derived1<int>&, Derived2<double>&>)' 
25:30: note: candidate is: 
15:6: note: template<class T1, class T2> void function(std::tuple<Base<T>&, Base<T2>&>) 
15:6: note: template argument deduction/substitution failed: 
25:30: note: mismatched types 'Base<T>' and 'Derived1<int>' 
25:30: note: 'std::tuple<Derived1<int>&, Derived2<double>&>' is not derived from 'std::tuple<Base<T>&, Base<T2>&>' 
1 Answers
Related