3

boost::interprocess::unique_ptr を返すファクトリ関数を作成しようとしています。次に例を示します。

#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
using namespace boost::interprocess;

class my_class {
public:
    my_class() {}
};

struct my_class_deleter {
    void operator()(my_class *p) {}
};

typedef unique_ptr<my_class, my_class_deleter> uptr;

uptr create() {
    return uptr();
}

int main() {
    uptr x;
    x = create();
    return 0;
}

問題は、gcc が上記のコードをコンパイルできないことです:

main.cpp:22: error: ambiguous overload for ‘operator=’ in ‘x = create()()’
../../boost_latest/boost/interprocess/smart_ptr/unique_ptr.hpp:211: note: candidates are: boost::interprocess::unique_ptr<T, D>& boost::interprocess::unique_ptr<T, D>::operator=(boost::rv<boost::interprocess::unique_ptr<T, D> >&) [with T = my_class, D = my_class_deleter]
../../boost_latest/boost/interprocess/smart_ptr/unique_ptr.hpp:249: note:                 boost::interprocess::unique_ptr<T, D>& boost::interprocess::unique_ptr<T, D>::operator=(int boost::interprocess::unique_ptr<T, D>::nat::*) [with T = my_class, D = my_class_deleter]

私が変わるとき

x = create();

x = boost::move(create());

それからgccは言う:

main.cpp:22: error: invalid initialization of non-const reference of type ‘uptr&’ from a temporary of type ‘uptr’
../../boost_latest/boost/move/move.hpp:330: error: in passing argument 1 of ‘typename boost::move_detail::enable_if<boost::has_move_emulation_enabled<T>, boost::rv<T>&>::type boost::move(T&) [with T = uptr]’

私は何か間違ったことをしていますか?

興味深いことに、私がするとき:

uptr x2 = create();

コードは問題なくコンパイルされます。

ところで: 私は gcc v4.4.3 と Boost v1.51.0 を使用しています。


アップデート:

次のスニペットを使用して、この問題を解決できました。

x = static_cast<boost::rv<uptr>&>(create());

operator=上記のキャストは、元の質問で言及されたあいまいなオーバーロードの最初のバージョンに基づいています。2 番目のもの ( operator=(int boost::interprocess::unique_ptr<T, D>::nat::*) は、おそらく、エミュレートするために実装によって提供されます。std::unique_ptr::operator=(nullptr_t)実際には、unique_ptr. 結局のところ、それはoperator=あいまいにもなります。

残念ながら、上記static_cast<>()を使用すると、工場の使用が複雑になりすぎます。

この問題を解決する 1 つの方法はoperator=、常に明示的に を呼び出すことができるため、の 2 番目のオーバーロードを削除することunique_ptr::reset()です。

boost::move()それでも、この問題を解決できるかどうか、またどのように役立つかは疑問です。

4

2 に答える 2

3

これは の実装におけるバグであることが判明しましたboost::interprocess:unique_ptr

ライブラリの管理者に報告しました (チケット #7598 )。

バグは修正されており、Boost v1.54.0 で修正が利用可能になります。

于 2013-01-22T12:12:32.793 に答える
0

ユースケースに合っているかどうかわかりませんが、unique_ptr を使用するのではなく、my_class を (Boost::Move を使用して) 移動可能な型にし、ファクトリ インターフェイスに Boost ValueFactory を使用して値によって物事を行うことはできませんか?

于 2012-11-22T15:54:34.017 に答える