テンプレートにT1とT2という2つの引数があるとします。 T1自体がテンプレート化されたクラス(コンテナなど)であり、T2には何でも構いませんが、T1の基本テンプレートタイプを判断し、T2を引数として使用して再構築することは可能ですか?テンプレートをC++の引数から分けることはできますか?
たとえば、私がstd::vector<int>
とstd::string
を受け取った場合、私は自動的にstd::vector<std::string>
を作りたいと思うでしょう。しかし、私にstd::set<bool>
とdouble
を与えた場合、それはstd::set<double>
を生成するでしょう。
ここでtype_traits、関連するブログ、その他の質問を確認したところ、この問題を解決するための一般的なアプローチはありません。私が現在この作業を達成するために見ることができる唯一の方法は、T1として渡すことができる各タイプのテンプレートアダプタを構築することです。例えば
、私が持っていた場合:
template<typename T_inner, typename T_new>
std::list<T_new> AdaptTemplate(std::list<T_inner>, T_new);
template<typename T_inner, typename T_new>
std::set<T_new> AdaptTemplate(std::set<T_inner>, T_new);
template<typename T_inner, typename T_new>
std::vector<T_new> AdaptTemplate(std::vector<T_inner>, T_new);
私はdecltypeを使用して、私の問題を解決するために、演算子オーバーロードに頼ることができるはずです。
template <typename T1, typename T2>
void MyTemplatedFunction() {
using my_type = decltype(AdaptTemplate(T1(),T2()));
}
何か不足していますか?より良いアプローチがありますか?
なぜこのようにしたいですか?
私は、ユーザーがモジュラーテンプレートを構築するために何をする必要があるか簡素化したいC++ライブラリを構築しています。たとえば、ユーザーがエージェントベースのシミュレーションを作成したい場合、生物型、母集団マネージャ、環境マネージャ、およびシステム管理者を持つWorldテンプレートを構成することができます。私はむしろ、多くのユーザーがNeuralNetworkAgent
たびに繰り返す必要がたくありません
World< NeuralNetworkAgent, EAPop<NeuralNetworkAgent>,
MazeEnvironment<NeuralNetworkAgent>,
LineageTracker<NeuralNetworkAgent> > world;
:
経営者の各々はまた、そう宣言は次のようになります、生物の種類を知っておく必要があります。私はテンプレート引数を変更することができました場合は、デフォルトの引数を使用することができ、上記のように単純化することができます。
World< NeuralNetworkAgent, EAPop<>, MazeEnvironment<>, LineageTracker<> > world;
プラスそれはタイプミスを気にせずに別の世界タイプから変換する方が簡単です。もちろん
、私はstatic_assertを使用して、ほとんどのエラーに対処し、ちょうど長い宣言に対処するが、私はよりよい解決策が可能であるかどうかを知りたいのですができます。
#include <vector>
#include <string>
template<typename T, typename ...U> class AdaptTemplateHelper;
template<template <typename...> class T, typename ...V, typename ...U>
class AdaptTemplateHelper<T<V...>, U...> {
public:
typedef T<U...> type;
};
template<typename T, typename ...U>
using AdaptTemplate=typename AdaptTemplateHelper<T, U...>::type;
void foo(const std::vector<std::string> &s)
{
}
int main()
{
AdaptTemplate<std::vector<int>, std::string> bar;
bar.push_back("AdaptTemplate");
foo(bar);
return 0;
}
ベストC++の質問今週:
私が得た3つの答えはすべて優れていました。 @Barryのものが最も徹底的で、T.C.私の根底にある問題を最も良く解決していますが、私が受け入れたSam Varshavchik(私が受け入れた)の回答は、私が尋ねたように質問を解決するための最もエレガントなものだと思います。みなさんありがとう! –
この投稿は重複しているので、@Ben Voightが指摘したものは非常に似ていますが、特にSTLに重点を置いていると思います。問題のテンプレートがすべて同じライブラリから来た場合は、確かに可能な余分なトリックがあります。それは、もう一つの質問にも面白くて有用な答えがあるということです。それは、ここで提供された回答が、この質問をよりターゲットとし、すぐに役立つことが分かりました。 –
他の質問はそれほど広範囲ではありませんが、答えはあなたのケースを完全にカバーしています。だからこそ私の旗は、「あなたの質問には既に答えがあります」というバナーが表示されます。 –