0

以下に示すように、本質的に異なるデフォルト以外のコンストラクタープロトタイプを持つ、デフォルト以外の構築可能なクラスのboost::variantオーバーセット(および、移動可能/コピー不可およびコピー/移動不可能なクラスでさえも)があります。

#include <boost/variant.hpp>
#include <string>
#include <list>

struct A { A(int) { ; } };
struct B { B(std::string) { ; } };
struct C { C(int, std::string) { ; } };

using V = boost::variant< A const, B const, C const >;
using L = std::list< V >;

int main()
{
    L l;
    l.push_back(A(1)); // an extra copy/move operation
    l.push_back(B("2")); // an extra copy/move operation
    l.push_back(C(3, "3")); // an extra copy/move operation
    l.emplace_back(4);
    l.emplace_back(std::string("5"));
    // l.emplace_back(3, std::string("3")); // error here
    return 0;
}

これにより、 /と/がある場合でも、std::list::emplace_back新しいオブジェクト (すべてのAB、型) を (1 回の操作で) リストに作成して挿入できると思います。しかし、コンストラクターが非変換の場合、どうすればよいですか? つまり、複数のパラメーターがあります。または、2 つの異なるバリアントの基になる型があいまいなコンストラクター プロトタイプを持っている場合はどうすればよいですか? 私の意見では、これは、 C++11 標準の新機能に照らして、問題を解決するために適用できるものがあるとすれば、ライブラリの実装の欠陥です。CT & operator = (T const &) = delete;T & operator = (T &&) = delete;T(T const &) = delete;T(T &&) = delete;boost::variant

私が知る限り、どちらもpimplイディオムを何らかの形で内部的に実装しているため (たとえば、一時的なヒープ バックアップ アプローチによって現在設計されています) std::listboost::variant重ね合わせについて具体的に尋ねました。boost::variant

4

2 に答える 2

1

「C」クラスを変更できると仮定すると、単一のタプル引数を取る追加のコンストラクターを与えることができます。

于 2013-05-16T12:04:02.743 に答える
1

emplace問題の型のコンストラクターのみを呼び出すことができます。Andboost::variantのコンストラクターは、バリアントの型の 1 つに明確に変換できる単一のオブジェクトのみを取ります。

variantパラメータをその境界型のいずれかに任意に転送しません。値を取るだけです。制限された型の 1 つに変換しようとする単一の値。

そのため、オブジェクトを構築してから、それを にコピーする必要がありvariantます。

于 2013-05-16T05:08:02.010 に答える