異なるSTLコンテナを受け入れるが、特定のクラスのオブジェクトを含む必要がある(例えば、std::vector<double>
とstd::deque<double>
を受け入れるはずだが、std::vector<std::string>
は受け入れない)という宣言をしたい。任意のコンテナを受け入れるテンプレート関数を宣言する
コンテナと含まれている型の両方をテンプレート化するための回答が見つかりましたが、包含された型が修正されるように修正しようとしましたが失敗しました。
異なるSTLコンテナを受け入れるが、特定のクラスのオブジェクトを含む必要がある(例えば、std::vector<double>
とstd::deque<double>
を受け入れるはずだが、std::vector<std::string>
は受け入れない)という宣言をしたい。任意のコンテナを受け入れるテンプレート関数を宣言する
コンテナと含まれている型の両方をテンプレート化するための回答が見つかりましたが、包含された型が修正されるように修正しようとしましたが失敗しました。
テンプレートテンプレートの引数(入力ミスなし)で行うことができます。テンプレート関数の最初のテンプレート引数は、可変個数のテンプレート引数を持つ別のテンプレートです。 2番目のテンプレート引数は、可変的なテンプレート引数です。署名では、最初のテンプレート引数を目的のタイプ(たとえばdouble
)に修正し、残りのものをコンパイラに推論させます。
#include <deque>
#include <iostream>
#include <string>
#include <vector>
template < template < class ... > class Container, class ... Args >
void any_container(Container<double, Args...>)
{
// print what was deduced
std::cout << __PRETTY_FUNCTION__ << '\n';
}
int main()
{
std::vector<double> vd;
any_container(vd);
std::deque<double> dd;
any_container(dd);
std::vector<std::string> vs;
any_container(vs); // BOOM!
}
@PasserByは、すでに別のソリューションin this commentを示唆しました。置換に失敗する代わりに、テンプレート引数としてコンテナを取り出し、クエリvalue_type
をstatic_assert
に入れることもできます。これには、カスタムエラーメッセージを入れることができるという利点があります。
#include <deque>
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
template <typename Container> void any_container(Container)
{
static_assert(std::is_same<typename Container::value_type, double>::value,
"BOOM!");
// print what was deduced
std::cout << __PRETTY_FUNCTION__ << '\n';
}
int main()
{
std::vector<double> vd;
any_container(vd);
std::deque<double> dd;
any_container(dd);
std::vector<std::string> vs;
any_container(vs); // BOOM!
}
'__PRETTY_FUNCTION__'は標準ではありません。これはGCCとClangで利用可能で、プリプロセッサの一部ではありません(例えば '__LINE__'とは対照的に)。 –
これを正しく理解すれば、ちょっとハックしているのでしょうか?私は毎回0になるテンプレート引数の可変数を使用すると述べていますが、そうでなければ可能ではない最初のパラメータを修正することができます。それですか? – user2891462
@ user2891462以下の代替ソリューションを参照してください。 –
*試したことはありますか?どのような問題があなたに与えられたのですか? –
^それ。ヒント: 'value_type' –
@PasserByあなたはアンリ・メンケの2番目の方法について話していますか?私は静的な主張を考えていましたが、より洗練された解決策があるかもしれないと考えました。 – user2891462