make_pair
次の単純なクラスを検討してください。
template <class X, class Y>
struct Pair
{
X x;
Y y;
};
また、移動/コピーを表示する単純なクラスを作成します。
struct C
{
C(int n_) : n(n_) {};
C(const C& x) { n = x.n; std::cout << "Copy: " << n << std::endl; }
C(C&& x) { n = x.n; std::cout << "Move: " << n << std::endl; }
int n;
};
次に、次を実行できます。
auto z1 = Pair<C, C>{C(1),C(2)};
出力C
はなく、移動もコピーもされません。
ただし、コンストラクターで型を指定する必要がありますPair
。これらを推測したいとしましょう。次のようなことができます。
template <class X, class Y>
Pair<X, Y> make_pair(X&& x, Y&& y)
{
return Pair<X, Y>{std::forward<X>(x), std::forward<Y>(y)};
}
そして、次のことができます。
auto z2 = make_pair(C(3),C(4));
しかし、これは次のように出力します:
Move: 3
Move: 4
ヒープ割り当てタイプであれば問題ありませんC
が、スタック割り当てタイプの場合、移動は基本的にコピーです。
しかし、このマクロを定義しましょう:
#define MAKE_PAIR(x,y) decltype(make_pair(x,y)){x,y}
次に、次のことができます。
auto z3 = MAKE_PAIR(C(5),C(6));
そして、これは型推論を行い、移動を必要としません。しかし、マクロを作成する必要がありますが、これは少し面倒で、演算子を使用してこの種のことを行うのを妨げています。
次のことを行うソリューションはありますか。
(1) 型を推測する (2 と 3 のように)
(2) コピーや移動を必要としない (1 と 3 のように)
(3) マクロを必要としない (1 と 2 のように)
私が得ることができる最高のものは3分の2ですが、確かに3分の3は可能ですか? どうやら C++ はマクロから遠ざかりつつあるので、C++ が私が求めていた動作を得るためにマクロを使用することを強制するとは想像できません。
コードはこちらです。