4

std::unique_ptrVisual Studio 2013 RC と C++を使用して、 を使用してバインドされた関数にを渡そうとしていstd::bindます。しかし、これを試してみるとVSが気に入らないようで困っています。ここに私がコンパイルしようとしているものがあります:

#include <memory>
#include <iostream>
#include <functional>

void func(std::unique_ptr<int> arg)
{
    std::cout << *arg << std::endl;
}

int main()
{
    std::function<void (std::unique_ptr<int>)> bound =
        std::bind(&func, std::placeholders::_1);

    std::unique_ptr<int> ptr(new int(42));
    bound(std::move(ptr));

    return 0;
}

これは GCC 4.8.1 でコンパイルされますが、VS2013 RC ではコンパイルされません。私は常に VS の移動セマンティクスに問題を抱えていましたが、生のポインターstd::unique_ptrの代わりに使用したいと思っています。std::shared_ptr

私が見つけた1つの回避策は、関数の署名を変更して を受け入れることstd::unique_ptr&です.私は特に醜いことをします:funcstd::unique_ptr

#include <memory>
#include <iostream>
#include <functional>
#include <future>
#include <string>

void func(std::unique_ptr<int>& arg)
{
    std::cout << *arg << std::endl;
}

int main()
{
    std::function<void (std::unique_ptr<int>&)> bound =
        std::bind(&func, std::placeholders::_1);

    std::unique_ptr<int> ptr(new int(42));
    std::promise<void> prom;
    std::async(
        [&bound, &ptr, &prom]
        {
            std::unique_ptr<int> movedPtr = std::move(ptr);
            prom.set_value();

            bound(std::move(movedPtr));
        });

    prom.get_future().wait();

    // Wait here
    std::string dummy;
    std::cin >> dummy;
}

funcの署名を変更せずにこれを回避する方法はありますか?

ありがとう!

4

3 に答える 3

2

最近、VS 2012 でも同じ問題が発生しました。これは MSVC のバグだと思います。少なくとも MSVC++11 では、疑似可変長展開は値によってパラメーターを内部関数に転送するようです。これは改善されていないようです。
回避策として、代わりにラムダを使用していますが、それを機能させるには別のハックが必要です。

std::function<void (std::unique_ptr<int>)> bound =
    [] (std::unique_ptr<int> arg) { func(std::move(arg)); };

まだコンパイルされません。ただし、キャプチャされた値 (使用されていないものでも) を追加すると、次のようにコンパイルされます。

int x;
std::function<void (std::unique_ptr<int>)> bound =
    [x] (std::unique_ptr<int> arg) { func(std::move(arg)); };
于 2013-10-11T11:37:01.727 に答える
0

バインドされた関数std::bindは引数を転送せず、それらを関数にコピーします。その結果、std::bindc++11 の時点では移動のみの型では機能しません。この問題は、「より完全な転送」 (このようなもの) の提案の背後にある考え方です。もっと新しいのがありますが、今は見つけられないようです。

于 2013-10-11T01:49:16.707 に答える