質問
私は、整数からのタプルのセットに、マップを作成する必要があり、単一のセット内のタプルは、同じサイズを持っています。問題は、タプルの大きさとそのパラメータの型は実行時ではなくコンパイル時に決定することができるということです。私のようなものを想像しています:
std::map<int, std::set<boost::tuple> >
ではなく、正確にbossiblyポインタを使用して、これを行う方法をexctlyてください。
この目的は、一時的なリレーション(テーブル)、一意の識別子(キー)を持つ各を作成することで、多分あなたは別のアプローチを持っています。
解決
boost::tuple
の目的は、任意の種類を混合することです。もし、あなたが言うように、
私は整数のみを挿入しています。
あなたはmap< int, set< vector< int > > >
を使用する必要があります。 (私があなただったら、私はそれにいくつかのtypedef
sを投げると思います。)
元の質問に答えるために、しかし、boost::tuple
は、実行時に任意の種類を許可していません。 boost::any
はありません。少しより多くの仕事がありますので、あなたがany
でそれを使用したい場合は、set
は比較をサポートしていません。
typedef vector< boost::any > tuple;
struct compare_tuple { bool operator()( tuple const &l, tuple const &r ) const {
assert ( l.size() == r.size() );
for ( tuple::iterator lit = l.begin(), rit = r.begin();
lit != l.end(); ++ lit, ++ rit ) {
assert ( lit->type() == rit->type() );
if ( lit->type() == typeid( foo ) ) { // find the type and perform "<"
return boost::any_cast<foo>(*lit) < boost::any_cast<foo>(*rit);
} else if ( lit->type() == typeid( bar ) ) {
return boost::any_cast<bar>(*lit) < boost::any_cast<bar>(*rit);
} /* etc; you will need to enumerate all the types you can insert */
}
} };
typedef std::map< int, std::set< tuple, compare_tuple > > main_map;
他のヒント
(以前の回答は2010年頃あるとして)、今日の可変個引数テンプレートは、このために有用であろう現代サイドノートとして:
template<typename... Args> //Accept any number of arguments and types
auto MyFunction(std::tuple<Args...> &T)->void
{
//Do stuff...
}
あなたは、同じコレクション内のこれらの異なるセットを保存することができます。あなたは抽象インタフェースを記述して、テーブル/タプルの各種類のためにそれを実装することができます。問題は通常、そのようなインタフェースは非常に厄介になる傾向があり、そしてあなたは、テーブル/タプルの多くの種類を持っている場合、あなたはおそらくクラス-爆発を持っているということ、です。 Boost.Any のようなインターフェースのために有用であり得ます(あなたは、動的に異なるデータ型を処理する必要があるため)。
パラメータの型が共通で何かを持っている場合は、抽象基底クラスにそれをキャプチャし、タプルが、この基底クラスへのポインタが含まれています。
class MyParamBase {
public:
virtual int getFoo() = 0;
virtual void setFoo(int) = 0;
};
std::map<int, std::set<MyParamBase*> > container;
(後押し::簡潔にするため省略タプルを。あなたはタプルのセットを必要とする理由わからない。)
あなたはその後、MyParamBaseから、具体的なパラメータの型を派生して作成し、マップにそれらを挿入することができます:
class SomeParam: MyParamBase {
public:
virtual int getFoo() { ... }
virtual void setFoo(int a) { ... }
};
std::set<MyParamBase*> some_set;
some_set.insert(new SomeParam());
container[123] = some_set;
パラメータタイプは共通点がない場合は- 同じマップに入れないでください。彼らは一緒に属していない可能性がかなります。