5

ペアを 2 つのローカル変数にアンパックするマクロを作成したいと思います。ペアが単なる変数である場合は、ペアのコピーを作成したくありません。これにより、次のことが実現します。

#define UNPACK_PAIR(V1, V2, PAIR) \
    auto& V1 = PAIR.first; \
    auto& V2 = PAIR.second;

UNPACK_PAIR(one, two, x);

ただし、複数回指定された式を評価しないようにしたいと思います。たとえば、これはexpensive_computation()1 回だけ呼び出す必要があります。

UNPACK_PAIR(one, two, expensive_computation());

私が行った場合:

#define UNPACK_PAIR_A(V1, V2, PAIR) \
    auto tmp = PAIR; \
    auto& V1 = tmp.first; \
    auto& V2 = tmp.second;

その後、ケースで機能しexpensive_computation()ますが、ケースでコピーを作成しますx。私が行った場合:

#define UNPACK_PAIR_R(V1, V2, PAIR) \
    auto& tmp = PAIR; \
    auto& V1 = tmp.first; \
    auto& V2 = tmp.second;

次にx、コピーを作成せずにケースで動作しますが、ケースで失敗しますexpensive_computation()。私が行った場合:

#define UNPACK_PAIR_CR(V1, V2, PAIR) \
    const auto& tmp = PAIR; \
    auto& V1 = tmp.first; \
    auto& V2 = tmp.second;

#define UNPACK_PAIR_RR(V1, V2, PAIR) \
    auto&& tmp = PAIR; \
    auto& V1 = tmp.first; \
    auto& V2 = tmp.second;

これらは両方ともコンパイルして実行しますが、未定義の動作を引き起こすと思われます-それについては正しいですか? また、これらのいずれかは意味がありますか?

#define UNPACK_PAIR_RR(V1, V2, PAIR) \
    auto&& tmp = std::move(PAIR); \
    auto& V1 = tmp.first; \
    auto& V2 = tmp.second;

#define UNPACK_PAIR_RR(V1, V2, PAIR) \
    auto&& tmp = std::forward<decltype(PAIR)>(PAIR); \
    auto& V1 = tmp.first; \
    auto& V2 = tmp.second;

これらのユース ケースの両方で機能するマクロを作成する方法はありxますか?

4

3 に答える 3

6

これにはマクロは必要ありません。

auto p = std::make_pair(2, 3);
int x, y;
std::tie(x, y) = p;

ペアの既存のメンバーへの参照が必要な場合:

auto p = std::make_pair(2, 3);
auto& x = p.first;
auto& y = p.second;

それでおしまい。

これで、より挑戦的/興味深い/重要なことに進むことができます.

于 2015-07-07T15:25:27.973 に答える
4

auto&&転送参照を作成します。つまり、何でも受け入れます。(常に)右辺値参照を作成するわけではありません。だからこれをしてください:

#define UNPACK_PAIR(V1, V2, PAIR) \
    auto&& tmp = PAIR; \
    auto& V1 = tmp.first; \
    auto& V2 = tmp.second;

ただし、これには反対することを強くお勧めします ( の使用の範囲UNPACK_PAIRが非常に限定されていて、操作がその範囲内で本当にどこにでもある場合を除きます)。それは私にとって何のメリットもないあいまいさのように見えます。6 か月後にプロジェクトに戻り、わずか 2 時間で重大なバグを見つけることを想像してみてください。読み取り可能なものの代わりに、非標準のマクロベースの構文を使用したことに感謝しますか?

于 2015-07-07T15:29:33.653 に答える
2

あなたが欲しいのはですstd::tie

decltype(p.first) x;
decltype(p.second) y;
std::tie(x,y) = p;

必要に応じて、それを使用してマクロを定義することもできます。これは 2 タプルでのみ機能することに注意してください。3 タプル以上が必要な場合は、少し異なる方法で行う必要があります。たとえば、3 タプルがある場合t:

decltype(std::get<0>(t)) x;
decltype(std::get<1>(t)) y;
decltype(std::get<2>(t)) z;
std::tie(x,y,z) = t;
于 2015-07-07T15:35:32.930 に答える