13

この投稿のフォローアップとしてmake_unique、次のコードのように、関数の一時バッファ配列を割り当てることで、その実装がどのように機能するのか疑問に思います。

f()
{
  auto buf = new int[n]; // temporary buffer
  // use buf ...
  delete [] buf;
}

これをへの呼び出しに置き換えることはできますか?make_uniqueその場合、[]-versionのdeleteが使用されますか?

4

2 に答える 2

19

(マイクに加えて)別の解決策は次のとおりです。

#include <type_traits>
#include <utility>
#include <memory>

template <class T, class ...Args>
typename std::enable_if
<
    !std::is_array<T>::value,
    std::unique_ptr<T>
>::type
make_unique(Args&& ...args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

template <class T>
typename std::enable_if
<
    std::is_array<T>::value,
    std::unique_ptr<T>
>::type
make_unique(std::size_t n)
{
    typedef typename std::remove_extent<T>::type RT;
    return std::unique_ptr<T>(new RT[n]);
}

int main()
{
    auto p1 = make_unique<int>(3);
    auto p2 = make_unique<int[]>(3);
}

ノート:

  1. 新しいT[n]は、デフォルトでnTを構成する必要があります。

したがって、make_unique(n)はデフォルトでnTを構成する必要があります。

  1. このような問題は、make_uniqueがC++11で提案されない原因となりました。もう1つの問題は、カスタム削除機能を処理するかどうかです。

これらは答えられない質問ではありません。しかし、それらはまだ完全には答えられていない質問です。

于 2012-04-14T01:14:03.337 に答える
4

私はそれをこのコードで動作させました:

#include <memory>
#include <utility>

namespace Aux {
    template<typename Ty>
    struct MakeUnique {
        template<typename ...Args>
        static std::unique_ptr<Ty> make(Args &&...args) {
            return std::unique_ptr<Ty>(new Ty(std::forward<Args>(args)...));
        }
    };

    template<typename Ty>
    struct MakeUnique<Ty []> {
        template<typename ...Args>
        static std::unique_ptr<Ty []> make(Args &&...args) {
            return std::unique_ptr<Ty []>(new Ty[sizeof...(args)]{std::forward<Args>(args)...});
        }
    };
}

template<typename Ty, typename ...Args>
std::unique_ptr<Ty> makeUnique(Args &&...args) {
    return Aux::MakeUnique<Ty>::make(std::forward<Args>(args)...);
}
于 2012-04-14T01:03:54.827 に答える