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

How to make std::make_unique a friend of my class(如何让 std::make_unique 成为我班的朋友)
本文介绍了如何让 std::make_unique 成为我班的朋友的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我想将 std::make_unique 函数声明为我班级的朋友.原因是我想声明我的构造函数 protected 并提供使用 unique_ptr 创建对象的替代方法.这是一个示例代码:

I want to declare std::make_unique function as a friend of my class. The reason is that I want to declare my constructor protected and provide an alternative method of creating the object using 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;
}

现在我收到此错误:

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

std::make_unique 声明为我班级朋友的正确方法是什么?

What is the correct way to declare std::make_unique as a friend of my class?

推荐答案

make_unique 完美转发你传递给它的参数;在您的示例中,您将左值 (x) 传递给函数,因此它会将参数类型推导出为 int&.你的 friend 函数声明需要

make_unique perfect forwards the arguments you pass to it; in your example you're passing an lvalue (x) to the function, so it'll deduce the argument type as int&. Your friend function declaration needs to be

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

同样,如果你要在 CreateAmove(x)friend 声明需要是

Similarly, if you were to move(x) within CreateA, the friend declaration would need to be

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

这将使代码编译,但绝不保证它会编译另一种实现,因为就您所知,make_unique 将其参数转发给另一个实际实例化您的类的内部辅助函数,在这种情况下,辅助函数需要是 friend.

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.

这篇关于如何让 std::make_unique 成为我班的朋友的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How do compilers treat variable length arrays(编译器如何处理变长数组)
Deduce template argument from std::function call signature(从 std::function 调用签名推导出模板参数)
check if member exists using enable_if(使用 enable_if 检查成员是否存在)
Standard Library Containers with additional optional template parameters?(具有附加可选模板参数的标准库容器?)
Uses of a C++ Arithmetic Promotion Header(C++ 算术提升标头的使用)
Parameter pack must be at the end of the parameter list... When and why?(参数包必须位于参数列表的末尾...何时以及为什么?)