Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 尝试将std::make_作为模板类的朋友声明为唯一时MSVC出错_C++_C++14_Unique Ptr_Friend Function_Msvc12 - Fatal编程技术网

C++ 尝试将std::make_作为模板类的朋友声明为唯一时MSVC出错

C++ 尝试将std::make_作为模板类的朋友声明为唯一时MSVC出错,c++,c++14,unique-ptr,friend-function,msvc12,C++,C++14,Unique Ptr,Friend Function,Msvc12,显然今天,MSVC正尽最大努力说服我改用clang。但我不会放弃。早些时候,我想知道如何声明std::make_unique为我班的朋友 在我的简单场景中,我得到了一个非常好的答案,事实上,当我用叮当声尝试它时,它编译得非常好 所以我很高兴回到VisualStudio2013继续编码。我的代码的一部分是: // other includes #include <string> #include <memory> template <typename Loader,

显然今天,MSVC正尽最大努力说服我改用clang。但我不会放弃。早些时候,我想知道如何声明
std::make_unique
为我班的
朋友

在我的简单场景中,我得到了一个非常好的答案,事实上,当我用叮当声尝试它时,它编译得非常好

所以我很高兴回到VisualStudio2013继续编码。我的代码的一部分是:

// 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)
    {
    }

// ...

};
//其他包括
#包括
#包括
模板
类模型
{
公众:
朋友std::unique\u ptr std::make\u unique(
常量std::字符串&,
const std::shared_ptr&,
const std::shared_ptr&);
//命名构造函数
静态std::unique_ptr CreateModel(
常量std::字符串和文件路径,
const std::共享装载机和装载机,
常数标准::共享(ptr和painter)
{
//如果错误长于《指环王》三部曲,请使用
//下面的行代替std::使_唯一
//return std::unique_ptr(新模型(文件路径、加载程序、画师));
return std::make_unique(文件路径、加载程序、绘制程序);
}
// ...
受保护的:
//建造师
模型(
常量std::字符串和文件路径,
const std::共享装载机和装载机,
常数标准::共享(ptr和painter)
:mFilepath(文件路径)
,装载机(装载机)
,mPainter(画家)
{
}
// ...
};
好吧,老实说,我没想到第一次就把它弄好了,但我相信我能从错误信息中理解一些道理:

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
1>d:\code\c++\projects\active\ele剑\src\Model/Model.hpp(28):错误C2063:'std::make_unique':不是函数
1> ..\..\src\Main.cpp(151):请参阅正在编译的类模板实例化“Model”的参考
显然,MSVC并不认为std::make_unique函数是一个函数

最糟糕的是我很累,我有种感觉,我错过了一些非常明显的东西。有人能帮我解开吗

另外,有人可以在Visual Studio 2015中尝试此功能吗?只是出于好奇


注意:我知道我可以(也可能应该)只使用
return std::unique_ptr(新模型(文件路径、加载程序、画师))但它感觉不太对劲。

尝试将std函数交给朋友会让你陷入危险境地,因为你对它们的实现做出了标准无法保证的假设。例如,您希望std::make_unique成为一个朋友,这样它就可以访问受保护的构造函数,但是如果std::make_unique的实现将此委托给其他一些秘密函数呢?你需要的是和这个秘密函数交朋友,但它是秘密的,所以你不能


其他复杂情况:标准没有明确规定std::make_unique的某些形式(尽管我认为这不适用于这个确切的示例)。在编译器完全支持可变模板之前,旧版本的VC++使用宏魔术模拟可变模板,因此虽然有std::make_unqiue,但它可能没有您期望的实际签名。

也没有在VS2015上编译,在我看来,它像MSVC bug。似乎它不会推断模板参数,您需要显式地指定它们。因此,如果我创建自己的非变量
make_unique
,然后将好友声明更改为
friend std::unique\p,您应该停止尝试与标准库中的某些内容交朋友。裁判官:嗯,我希望vs2015不会有这个问题。如果我想让我的项目在所有编译器上运行,我想最好忘记这种方法。顺便说一下,这是个不错的解决办法。我可以使用它或者类似的东西。一种常见的技术是使用公共构造函数,它需要一个私有标记类型的实例来调用。是的,这是绝对有意义的。你是对的。谢谢你的回答!