简体   繁体   English

如何让std :: make_unique成为我班级的朋友

[英]How to make std::make_unique a friend of my class

I want to declare std::make_unique function as a friend of my class. 我想将std::make_unique函数声明为我班级的朋友。 The reason is that I want to declare my constructor protected and provide an alternative method of creating the object using unique_ptr . 原因是我想声明我的构造函数protected并提供使用unique_ptr创建对象的替代方法。 Here is a sample code: 这是一个示例代码:

#include <memory>

template <typename T>
class A
{
public:
    // Somehow I want to declare make_unique as a friend
    friend std::unique_ptr<A<T>> std::make_unique<A<T>>();


    static std::unique_ptr<A> CreateA(T x)
    {
        //return std::unique_ptr<A>(new A(x)); // works
        return std::make_unique<A>(x);         // doesn't work
    }

protected:
    A(T x) { (void)x; }
};

int main()
{
    std::unique_ptr<A<int>> a = A<int>::CreateA(5);
    (void)a;
    return 0;
}

Right now I get this error: 现在我收到此错误:

Start
In file included from prog.cc:1:
/usr/local/libcxx-head/include/c++/v1/memory:3152:32: error: calling a protected constructor of class 'A<int>'
return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
                           ^
prog.cc:13:21: note: in instantiation of function template specialization 'std::__1::make_unique<A<int>, int &>' requested here
    return std::make_unique<A>(x);     // doesn't work
                ^
prog.cc:22:41: note: in instantiation of member function 'A<int>::CreateA' requested here
std::unique_ptr<A<int>> a = A<int>::CreateA(5);
                                    ^
prog.cc:17:5: note: declared protected here
A(T x) { (void)x; }
^
1 error generated.
1
Finish

What is the correct way to declare std::make_unique as a friend of my class? std::make_unique声明为我班级的朋友的正确方法是什么?

make_unique perfect forwards the arguments you pass to it; make_unique完美地转发你传递给它的论据; in your example you're passing an lvalue ( x ) to the function, so it'll deduce the argument type as int& . 在你的例子中,你将左值( x )传递给函数,因此它将参数类型推导为int& Your friend function declaration needs to be 您的friend功能声明需要

friend std::unique_ptr<A> std::make_unique<A>(T&);

Similarly, if you were to move(x) within CreateA , the friend declaration would need to be 同样,如果你要在CreateA move(x) ,那么friend声明就需要

friend std::unique_ptr<A> std::make_unique<A>(T&&);

This will get the code to compile , but is in no way a guarantee that it'll compile on another implementation because for all you know, make_unique forwards its arguments to another internal helper function that actually instantiates your class, in which case the helper would need to be a friend . 这将获得编译的代码,但绝不保证它将在另一个实现上编译,因为据你所知, make_unique将其参数转发给实际实例化你的类的另一个内部帮助函数,在这种情况下帮助器会需要成为friend

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM