1

unique_ptrの醜さを隠すための次の「トリック」の何が問題になっていますか?

class Drawable;
typedef unique_ptr<Drawable> pDrawable;
#define newDrawable(...) pDrawable(new Drawable (##__VA_ARGS__))

最初の2つは問題ありません。しかし、3つ目は、VS2012でエラーを引き起こしています。

 23 IntelliSense: "std::unique_ptr<_Ty, _Dx>::unique_ptr(const std::unique_ptr<_Ty, _Dx>::
_Myt &) [with _Ty=Drawable, _Dx=std::default_delete<Drawable>]" (declared at line 1447 of
"C:\vs2012\VC\include\memory") is inaccessible  file.h  36  26  

C ++定義マクロがどのように機能するかを誤解しない限り、これが機能しない理由はわかりません。私はそれが単にこのコードを置き換えるだろうと思いました:

newDrawable(a, b, c)

unique_ptr<Drawable>(new Drawable(a, b, c));

unique_ptrをコピーできないことは理解していますが、ここではコピーしていません。私ですか?

編集:

問題のマクロの「使用」に関するいくつかのリクエストを受け取りました。

それを使用する場合、それは次のように使用されます:

pDrawable myDraw = newDrawable();

私が翻訳したいのは:

unique_ptr<Drawable> myDraw = unique_ptr<Drawable>(new Drawable());

ただし、Visual Studioで以下のエラーが発生しない限り、マクロをコンパイルすることはできません。それ自体、#defineの何かが許されないかのようです。エラーは、defineを呼び出した場所ではなく、defineを作成した行に返されます。

make_uniqueが機能しない理由についてはこちらをご覧ください:make_uniqueはコンパイルされません

edit2

以下の質問に答えました。上記のコードはコンパイルされ、機能します。

4

2 に答える 2

14

ええと、#define私見は、スコープのルールに従わず、時には驚くべき結果をもたらす可能性のある単純なテキスト置換を行うため、大きな問題です。何かをする必要があるときは、プリプロセッサマクロが最後の手段だと思います。

make_sharedを返すようなテンプレートを定義する方がはるかに良いでしょうunique_ptr<T>。その後、所定の位置に移動できるため、これは許容されます。

auto a_drawable = make_unique<Drawable>(a, b, c);

template <typename T, typename... Args>
::std::unique_ptr<T> make_unique(Args&&... args)
{
    return ::std::unique_ptr<T>{new T(::std::forward<Args>(args)...)};
}

これはマクロよりもはるかにクリーンで、配列以外のタイプでも機能します。これは問題です。配列型でも機能するようにすることもできますが、そのコードはもう少し複雑なので、繰り返すのではなく、役立つコメント投稿者が私に紹介した答えを指摘します。

マクロを使用したときにエラーが発生する理由については、よくわかりません。結果がに変換されるコンテキストでマクロを使用しているように見えます。const ::std::unique_ptr<Drawable> &次に、マクロを別のに移動しようとしpDrawableます。これは機能しません。なぜそれが起こっているのか、私にはわかりません。それはあなたがマクロを使用している文脈に決定的に依存します、そしてあなたはそれを提供していません。

そして、それは私の最初のポイントを強調しています。マクロが本当に醜い理由の1つは、マクロが単純なテキスト置換であり、コンテキストに応じてその意味が変わる可能性があるためです。

于 2013-02-07T00:33:33.780 に答える
2

答え:

実際にマクロを使用していることを確認してください。そうすれば、すべて問題ありません。

どうやら、#defineマクロを検証する試みで、VC++はマクロの実際の使用をチェックします。コンパイルされたマクロが実際に使用されていない場合、VC ++はそれを「理解」しようとし、コンパイラエラーをスローする可能性があります。

魔法のように、私が追加した場合:

pDrawable myDraw = newDrawable();

上記のコードの後、エラーは消えます。

みんなの時間を無駄にしてすみません。少なくともこれは私に次の記事を読むように促しました:

http://blogs.msdn.com/b/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx

于 2013-02-07T07:03:26.487 に答える