Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++ 如何提高::让你和我班的一个朋友分享_C++_Templates_Boost_Friend_Make Shared - Fatal编程技术网

C++ 如何提高::让你和我班的一个朋友分享

C++ 如何提高::让你和我班的一个朋友分享,c++,templates,boost,friend,make-shared,C++,Templates,Boost,Friend,Make Shared,我用受保护的构造函数编写了一个类,因此新实例只能用一个静态create()函数生成,该函数将共享的\u ptr返回给我的类。为了提供有效的分配,我希望在create函数中使用boost::make_shared,但是编译器抱怨我的类构造函数在boost::make_shared中受到保护。我决定让我的boost::make_与我班的一位朋友共享,但我对语法感到困惑。我试过了 template< class T, class A1, class A2 > friend boost::s

我用受保护的构造函数编写了一个类,因此新实例只能用一个静态create()函数生成,该函数将共享的\u ptr返回给我的类。为了提供有效的分配,我希望在create函数中使用boost::make_shared,但是编译器抱怨我的类构造函数在boost::make_shared中受到保护。我决定让我的boost::make_与我班的一位朋友共享,但我对语法感到困惑。我试过了

template< class T, class A1, class A2 >
friend boost::shared_ptr<Connection> boost::make_shared(const ConnectionManagerPtr&, const std::string&);
模板
friend boost::shared_ptr boost::make_shared(const connectionmanager&,const std::string&);

但是编译器给了我语法错误。请帮助。

如果没有
模板
部分,我会尝试。毕竟,您希望(模板)函数的特定实例化成为类的朋友,不是吗?做

friend boost::shared_ptr<Connection> boost::make_shared(const ConnectionManagerPtr&, const std::string&);
friend boost::shared\u ptr boost::make_shared(const connectionmanager&,const std::string&);
工作


如果这不是解决方案,那么向我们提供您获得的编译器消息可能会有所帮助…

我认为这不是使用make_shared的正确位置。只需使用new运算符构造对象,并将指针传递给shared_ptr构造函数。这样你就不需要和任何人做朋友了


顺便说一句,为什么模板参数和函数参数的类型不同?

您不需要为
friend
部分设置模板,但需要表明
friend
函数是一个模板:

friend boost::shared_ptr<Connection> boost::make_shared<>(/* ... */);
//                                                     ^^

只是一个完整版本的摘要:

#include <iostream>
#include <boost/make_shared.hpp>

class Foo {
  explicit Foo(int x) {
    std::cout << "Foo::Foo(" << x << ")\n";
  }
public:
  friend boost::shared_ptr<Foo> boost::make_shared<Foo, int>(const int& x);

  static boost::shared_ptr<Foo> create(int x) {
    return boost::make_shared<Foo, int>(x);
  }

  ~Foo() {
    std::cout << "Foo::~Foo()\n";
  }
};

int main(int argc, const char *argv[]) {
  Foo::create(42);
}
#包括
#包括
福班{
显式Foo(intx){

std::cout下面是我为您编写的一些宏。在您的情况下,您可以使用:

BOOST_MAKE_SHARED_2ARG_CONSTRUCTOR(Connection, const ConnectionManagerPtr&, const std::string&);
宏定义:

// Required includes
#include <boost/make_shared.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_const.hpp> 

// Helper macro
#define CONST_REFERENCE(T) boost::add_reference<boost::add_const<T>::type>::type

/** BOOST_MAKE_SHARED_nARG_CONSTRUCTOR(CLASS_NAME, ARG1_TYPE, ARG2_TYPE, ...) 
  *
  * Use this macro inside the body of a class to declare that boost::make_shared
  * should be considered a friend function when used in conjunction with the
  * constructor that takes the given argument types.  This allows the constructor 
  * to be declared private (making it impossible to accidentally create an instance 
  * of the object without immediatly storing it in a boost::shared_ptr).  
  * Example usage:
  *
  * class Foo {
  *   private:
  *     Foo(int size, const char* name);
  *     MAKE_SHARED_2ARG_CONSTRUCTOR(Foo, int, const char*);
  * };
  * 
  * boost::shared_ptr<Foo> myFoo = boost::make_shared<Foo>(3, "Bob");
  *
  * Note that you need to explicitly specify the number of arguments 
  * that the constructor takes as part of the macro name.  Also, note that 
  * macros don't mix well with templated types that contain commas -- so 
  * if you have such a type, then you should typedef it to a shorter name 
  * before using it with this macro.
  */
#define BOOST_MAKE_SHARED_0ARG_CONSTRUCTOR(CLASS_NAME) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>()
#define BOOST_MAKE_SHARED_1ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1))
#define BOOST_MAKE_SHARED_2ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2))
#define BOOST_MAKE_SHARED_3ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3))
#define BOOST_MAKE_SHARED_4ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4))
#define BOOST_MAKE_SHARED_5ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5))
#define BOOST_MAKE_SHARED_6ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6))
#define BOOST_MAKE_SHARED_7ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6, ARG_TYPE7) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6)), CONST_REFERENCE(ARG_TYPE7))
#define BOOST_MAKE_SHARED_8ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6, ARG_TYPE7, ARG_TYPE8) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6)), CONST_REFERENCE(ARG_TYPE7)), CONST_REFERENCE(ARG_TYPE8))
#define BOOST_MAKE_SHARED_9ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6, ARG_TYPE7, ARG_TYPE8, ARG_TYPE9) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6)), CONST_REFERENCE(ARG_TYPE7)), CONST_REFERENCE(ARG_TYPE8)), CONST_REFERENCE(ARG_TYPE9))
//必需包括
#包括
#包括
#包括
//辅助宏
#定义常量引用(T)boost::add\u REFERENCE::type
/**BOOST\u MAKE\u SHARED\u nARG\u构造函数(类名称、ARG1\u类型、ARG2\u类型,…)
*
*在类的主体内使用此宏来声明boost::make_shared
*当与一起使用时,应将其视为友元函数
*采用给定参数类型的构造函数。这允许
*声明为私有(使得不可能意外地创建实例
*在不立即将其存储在boost::shared\u ptr中的情况下对该对象进行复制。
*用法示例:
*
*福班{
*私人:
*Foo(整数大小,常量字符*名称);
*MAKE_SHARED_2ARG_构造函数(Foo,int,const char*);
* };
* 
*boost::shared_ptr myFoo=boost::make_shared(3,“Bob”);
*
*请注意,您需要显式指定参数的数量
*构造函数作为宏名称的一部分
*宏不能与包含逗号的模板化类型很好地混合,所以
*如果您有这样一个类型,那么您应该将其定义为一个较短的名称
*在将其与此宏一起使用之前。
*/
#定义BOOST\u MAKE\u SHARED\u 0ARG\u构造函数(类名称)\
friend boost::shared_ptr boost::make_shared()
#定义BOOST\u MAKE\u SHARED\u 1ARG\u构造函数(类名称,ARG\u类型1)\
friend boost::shared_ptr boost::make_shared(常量参考(ARG_类型1))
#定义BOOST_MAKE_SHARED_2ARG_构造函数(类名称、ARG_类型1、ARG_类型2)\
friend boost::shared_ptr boost::make_shared(常量引用(ARG_类型1),常量引用(ARG_类型2))
#定义BOOST_MAKE_SHARED_3ARG_构造函数(类名称、ARG_类型1、ARG_类型2、ARG_类型3)\
friend boost::shared_ptr boost::make_shared(常量引用(ARG_类型1)、常量引用(ARG_类型2)、常量引用(ARG_类型3))
#定义BOOST_MAKE_SHARED_4ARG_构造函数(类名称、ARG_类型1、ARG_类型2、ARG_类型3、ARG_类型4)\
friend boost::shared_ptr boost::make_shared(常量引用(ARG_类型1)、常量引用(ARG_类型2)、常量引用(ARG_类型3)、常量引用(ARG_类型4))
#定义BOOST_MAKE_SHARED_5ARG_构造函数(类名称、ARG_类型1、ARG_类型2、ARG_类型3、ARG_类型4、ARG_类型5)\
friend boost::shared_ptr boost::make_shared(常量参考(ARG_类型1)、常量参考(ARG_类型2)、常量参考(ARG_类型3)、常量参考(ARG_类型4)、常量参考(ARG_类型5))
#定义BOOST_MAKE_SHARED_6ARG_构造函数(类名称、ARG_类型1、ARG_类型2、ARG_类型3、ARG_类型4、ARG_类型5、ARG_类型6)\
friend boost::shared_ptr boost::make_shared(常量参考(ARG_类型1)、常量参考(ARG_类型2)、常量参考(ARG_类型3)、常量参考(ARG_类型4)、常量参考(ARG_类型5)、常量参考(ARG_类型6))
#定义BOOST_MAKE_SHARED_7ARG_构造函数(类名称、ARG_类型1、ARG_类型2、ARG_类型3、ARG_类型4、ARG_类型5、ARG_类型6、ARG_类型7)\
friend boost::shared_ptr boost::make_shared(常量参考(ARG_类型1)、常量参考(ARG_类型2)、常量参考(ARG_类型3)、常量参考(ARG_类型4)、常量参考(ARG_类型5)、常量参考(ARG_类型6))、常量参考(ARG_类型7))
#定义BOOST_MAKE_SHARED_8ARG_构造函数(类名称、ARG_类型1、ARG_类型2、ARG_类型3、ARG_类型4、ARG_类型5、ARG_类型6、ARG_类型7、ARG_类型8)\
friend boost::shared_ptr boost::make_shared(常量参考(ARG_类型1)、常量参考(ARG_类型2)、常量参考(ARG_类型3)、常量参考(ARG_类型4)、常量参考(ARG_类型5)、常量参考(ARG_类型6))、常量参考(ARG_类型7))、常量参考(ARG_类型8))
#定义BOOST_MAKE_SHARED_9ARG_构造函数(类名称、ARG_类型1、ARG_类型2、ARG_类型3、ARG_类型4、ARG_类型5、ARG_类型6、ARG_类型7、ARG_类型8、ARG_类型9)\
friend boost::shared_ptr boost::make_shared(常量参考(ARG_类型1)、常量参考(ARG_类型2)、常量参考(ARG_类型3)、常量参考(ARG_类型4)、常量参考(ARG_类型5)、常量参考(ARG_类型6))、常量参考(ARG_类型7))、常量参考(ARG_类型8))、常量参考(ARG_类型9))

我最终使用以下简单的解决方案来强制实施共享所有权。不需要友谊

class probe {
    probe() = default;
    probe(...) { ... }

    // Part I of III, private
    struct creation_token {};
    probe(probe const&) = delete;
    probe& operator=(probe const&) = delete;

public:
    // Part II of III, public
    template <class... Args>
    probe(creation_token&&, Args&&... args):
        probe(std::forward<Args>(args)...) {}

    // Part III of III, public
    template <class... Args>
    static auto create(Args&&... args) {
        return make_shared<probe>(creation_token(),
            std::forward<Args>(args)...);
    }
};
类探测{
probe()=默认值;
探测(…){…}
//第二部分第一部分
// Required includes
#include <boost/make_shared.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_const.hpp> 

// Helper macro
#define CONST_REFERENCE(T) boost::add_reference<boost::add_const<T>::type>::type

/** BOOST_MAKE_SHARED_nARG_CONSTRUCTOR(CLASS_NAME, ARG1_TYPE, ARG2_TYPE, ...) 
  *
  * Use this macro inside the body of a class to declare that boost::make_shared
  * should be considered a friend function when used in conjunction with the
  * constructor that takes the given argument types.  This allows the constructor 
  * to be declared private (making it impossible to accidentally create an instance 
  * of the object without immediatly storing it in a boost::shared_ptr).  
  * Example usage:
  *
  * class Foo {
  *   private:
  *     Foo(int size, const char* name);
  *     MAKE_SHARED_2ARG_CONSTRUCTOR(Foo, int, const char*);
  * };
  * 
  * boost::shared_ptr<Foo> myFoo = boost::make_shared<Foo>(3, "Bob");
  *
  * Note that you need to explicitly specify the number of arguments 
  * that the constructor takes as part of the macro name.  Also, note that 
  * macros don't mix well with templated types that contain commas -- so 
  * if you have such a type, then you should typedef it to a shorter name 
  * before using it with this macro.
  */
#define BOOST_MAKE_SHARED_0ARG_CONSTRUCTOR(CLASS_NAME) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>()
#define BOOST_MAKE_SHARED_1ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1))
#define BOOST_MAKE_SHARED_2ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2))
#define BOOST_MAKE_SHARED_3ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3))
#define BOOST_MAKE_SHARED_4ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4))
#define BOOST_MAKE_SHARED_5ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5))
#define BOOST_MAKE_SHARED_6ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6))
#define BOOST_MAKE_SHARED_7ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6, ARG_TYPE7) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6)), CONST_REFERENCE(ARG_TYPE7))
#define BOOST_MAKE_SHARED_8ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6, ARG_TYPE7, ARG_TYPE8) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6)), CONST_REFERENCE(ARG_TYPE7)), CONST_REFERENCE(ARG_TYPE8))
#define BOOST_MAKE_SHARED_9ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6, ARG_TYPE7, ARG_TYPE8, ARG_TYPE9) \
    friend boost::shared_ptr<CLASS_NAME> boost::make_shared<CLASS_NAME>(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6)), CONST_REFERENCE(ARG_TYPE7)), CONST_REFERENCE(ARG_TYPE8)), CONST_REFERENCE(ARG_TYPE9))
class probe {
    probe() = default;
    probe(...) { ... }

    // Part I of III, private
    struct creation_token {};
    probe(probe const&) = delete;
    probe& operator=(probe const&) = delete;

public:
    // Part II of III, public
    template <class... Args>
    probe(creation_token&&, Args&&... args):
        probe(std::forward<Args>(args)...) {}

    // Part III of III, public
    template <class... Args>
    static auto create(Args&&... args) {
        return make_shared<probe>(creation_token(),
            std::forward<Args>(args)...);
    }
};