5

どうやら今日、MSVC は私に clang への切り替えを説得するために最善を尽くしているようです。しかし、私はあきらめません。以前、クラスのとして宣言する方法を考えて、この質問をしました。std::make_uniquefriend

単純なシナリオでかなり良い答えが得られました。実際、wandboxで clang を使用して試してみると、問題なくコンパイルされました。

そのため、Visual Studio 2013 に戻ってコーディングを続けています。私のコードの一部はこれです:

// other includes
#include <string>
#include <memory>

template <typename Loader, typename Painter, typename MeshT>
class Model
{
public:
    friend std::unique_ptr<Model> std::make_unique<Model>(
        const std::string&,
        const std::shared_ptr<Loader>&,
        const std::shared_ptr<Painter>&);

    // Named constructor
    static std::unique_ptr<Model> CreateModel(
        const std::string& filepath,
        const std::shared_ptr<Loader>& loader,
        const std::shared_ptr<Painter>& painter)
    {
        // In case of error longer than the Lord of the Rings trilogy, use the
        // line below instead of std::make_unique
        //return std::unique_ptr<Model>(new Model(filepath, loader, painter));
        return std::make_unique<Model>(filepath, loader, painter);
    }

// ...
protected:
    // Constructor
    Model(
        const std::string& filepath,
        const std::shared_ptr<Loader>& loader,
        const std::shared_ptr<Painter>& painter)
        : mFilepath(filepath)
        , mLoader(loader)
        , mPainter(painter)
    {
    }

// ...

};

正直なところ、最初はうまくいくとは思っていませんでしたが、エラーメッセージからある程度理解できると確信していました。

1>d:\code\c++\projects\active\elesword\src\Model/Model.hpp(28): error C2063: 'std::make_unique' : not a function
1>          ..\..\src\Main.cpp(151) : see reference to class template instantiation 'Model<AssimpLoader,AssimpPainter,AssimpMesh>' being compiled

std::make_unique どうやら、MSVC は関数が関数であるとは考えていません。

最悪の部分は、私が疲れていて、非常に非常に(...) 明らかな何かが欠けていると感じていることです. 誰でも私が立ち往生するのを助けることができますか?

また、誰でも Visual Studio 2015 でこれを試すことができますか? 単なる好奇心から..

注:使用できる (そしておそらく使用する必要がある) ことはわかっていますreturn std::unique_ptr<Model>(new Model(filepath, loader, painter));が、正しくないと感じています。

4

1 に答える 1

8

std 関数を友達にしようとすると、標準で保証されていない実装について仮定しているため、危険な領域に陥ります。たとえば、保護されたコンストラクターにアクセスできるように std::make_unique をフレンドにしたいのですが、std::make_unique の実装がこれを他のシークレット関数に委任するとどうなるでしょうか? その場合に必要なのは、その秘密の機能と友達になることですが、それは秘密であるため、できません。

その他の複雑さ: std::make_unique の一部の形式は、標準で正確に指定されていません (ただし、この正確な例には当てはまらないと思います)。コンパイラが可変個引数テンプレートを完全にサポートする前に、VC++ の古いバージョンは可変個引数テンプレートをシミュレートするためにマクロ マジックを使用していました。

于 2015-11-25T18:17:39.997 に答える