以下のコードでは、テンプレート引数がテンプレートの場合、クラス テンプレートは 1 つのパラメーターを使用しますが、関数テンプレートは 2 つを使用します。これは、型推論を使用する場合は問題ありませんが、明示的なテンプレートのインスタンス化を使用する場合は奇妙です。
テンプレート テンプレート パラメータを 1 つのパラメータとして記述することは可能ですか?
この質問は、関数オーバーロード マッチング テンプレート テンプレートにリンクされています
#include <iostream>
template <typename T>
struct C
{
C (T i)
{
std::cout << "simple" << std::endl;
}
};
template <template<typename TT> class FF, typename TT>
struct C <FF<TT> > // (1)
{
C (FF<TT> i)
{
std::cout << "template" << std::endl;
}
};
template <typename T>
void F (T i)
{
std::cout << "simple" << std::endl;
}
// two template arguments FF and TT.
// Anyway to write this so that the argument count is one?
template <template<typename TT> class FF, typename TT>
void F (FF<TT> i)
{
std::cout << "template" << std::endl;
}
template <typename T>
struct R
{
T x;
};
int main()
{
R<int> r;
C<R<int> >{r}; // prints 'template', as expected
F<R<int> >(r); // prints 'simple', probably not what you think
F<R,int >(r); // prints 'template' as expected but
}
編集:
1 つのパラメーター構文がある場合、オーバーロードの解決で間違った関数が選択されるため、この質問は適切ではないという結論に達しました。これは私には驚きですが、これを証明するコードは次のとおりです (変更された 1 つのテンプレート関数のオーバーロードを除いて、以前と同じコード)。
EDIT2: 明示的なテンプレートの指定をスキップして、メインにさらに印刷を追加しました。
EDIT3: 以下のコードはナンセンスです。@DyPが正しく指摘したように、私は間違いを犯しました。私はvoid F(R<R<T>>)
明示的なケースで呼び出していますが、 ではありませんvoid F(R<T>)
。
#include <iostream>
template <typename T>
struct R
{
T x;
};
template <typename T>
struct C
{
C (T i)
{
std::cout << "simple" << std::endl;
}
};
template <template<typename TT> class FF, typename TT>
struct C <FF<TT> > // (1)
{
C (FF<TT> i)
{
std::cout << "template" << std::endl;
}
};
template <typename T>
void F (R<T> i)
{
std::cout << "template" << i.x << std::endl;
}
template <typename T>
void F (T i)
{
std::cout << "simple" << std::endl;
}
int main()
{
R<int> r;
C<R<int> >{r}; // prints 'template', as expected
F<R<int> >(r); // prints 'simple', probably not the expected overload
F (r); // prints 'template', now overload resolution works. Strange.
}