古いコードで C++10 の新機能を利用しているときに、make_shared
12 個のパラメーターを使用して呼び出すことができないという問題が発生しました。make_shared
Microsoft の STL で、エミュレーションをどのように使用しているか、10 が最大であると話しているのを覚えています。明らかに、これのためだけにコードをリファクタリングすることは問題外なので、基本的に私の質問はmake_shared
、VS 2010 で10 個を超えるパラメーターを取得する方法はありますか?
2 に答える
make_shared<foobar>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
で置き換えることができます
shared_ptr<foobar>(new foobar(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
C++11 では、std::make_shared は実際には 2 番目の方法を使用してオブジェクトを作成するよりもパフォーマンスを最適化します。これは、メモリ割り当てを 2 つではなく 1 つしか実行しないためです。ただし、変数が 10 個を超えると、選択の余地はあまりありません。使用するものについて。
make_shared
その効率的な利点を本当に使用したい場合でも、そうすることができます:
#include <tuple>
#include <memory>
#include <redi/index_tuple.h>
template<typename X, typename... Args>
std::shared_ptr<X>
make_shared_TO_THE_MAX(Args&&... args)
{
struct Wrapper
{
X x;
template<typename... T>
Wrapper(std::tuple<T...> targs) : Wrapper(targs, to_index_tuple<T...>{}) { }
template<typename T, unsigned... I>
Wrapper(T targs, index_tuple<I...>) : x(std::get<I>(targs)) { }
};
auto wrapped = std::make_shared<Wrapper>(std::forward_as_tuple(std::forward<Args>(args)...));
return std::shared_ptr<X>(wrapped, &wrapped->x);
}
これにより、コンストラクターの引数が参照のタプルにまとめられ、それが に渡されます。1 つしか取得できないため、10 個の引数を処理できなくmake_shared
ても問題ありません。which を使用するmake_shared
代わりに、 ( type のメンバーと同じサイズとレイアウトである) a にスペースを割り当て、引数タプルで構築します。コンストラクターは、タプルを展開してコンストラクターに渡す別のコンストラクターに委譲します。make_shared<X>
make_shared<Wrapper>
Wrapper
X
Wrapper
X
最後に、shared_ptr
エイリアシング コンストラクタを使用して、shared_ptr<X>
と所有権を共有するが、オブジェクトshared_ptr<Wrapper>
のアドレスを格納するを返します。X
<redi/index_tuple.h>
私自身のヘッダーですが、C ++ 14用に標準化された同様のものを取得しようとしています。
これは可変個引数テンプレートなしでも実行できますが、より多くの作業が必要です。これは引数が 2 つの場合です。12 の場合はさらに 10 を追加してください。
#include <tuple>
#include <memory>
template<typename X, typename Arg0, typename Arg1>
std::shared_ptr<X>
make_shared_TO_THE_MAX(Arg0&& arg0, Arg1&& arg1)
{
struct Wrapper
{
X x;
template<typename T0, typename T1>
Wrapper(std::tuple<T0, T1> targs)
: x(std::get<0>(targs), std::get<1>(targs)) { }
};
auto wrapped = std::make_shared<Wrapper>(std::forward_as_tuple(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1)));
return std::shared_ptr<X>(wrapped, &wrapped->x);
}