std::tuple
の参照基底クラスを受け取る関数に、引数として参照派生クラスのstd::tuple
を渡そうとすると、テンプレート引数の減算が失敗します。なぜコンパイラはテンプレート引数T1
とT2
を推測できないのですか?どのように修正できますか?std :: tupleとテンプレート派生クラスでテンプレート引数の控除/置換が失敗するのはなぜですか?
// 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 */
}
これは、ラインコード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>&>'
答えは基本的に控除が嫌いです。 'Base&'の引数に 'Double &'を導くことは幸いではありません。私は、誰かに標準的な習得者が実際の答えを書くのをもっと堪能にさせます。 –
cdhowie
'std :: tuple'は、std :: tuple とは異なり、別のクラスです。 2つの間に暗黙的な変換はありません。ユーザー定義の変換はありますが、テンプレート引数の控除の際には考慮されません。 –
@cdhowie 'Derived1'のlvalue引数から' Base & 'を推論するのは実際にはうまくいきます。関数の引数がクラス型の場合、直接減算が失敗した場合でも引数型の基底クラスも考慮されるからです。しかし、ここでの問題は、引数型自体にのみ適用され、 'std :: tuple'の内部で使用されるテンプレートパラメータ/引数のような他のコンテキストはありません。あるいは、別の方法で見ると、2つの 'tuple'型の関係は、ユーザ定義の変換であり、導出 - ベースの関係ではありません。 –
aschepler