【问题标题】:Template factory function with additional args: friendship issue带有附加参数的模板工厂功能:友谊问题
【发布时间】:2015-01-05 17:09:34
【问题描述】:

我正在编写如下代码:

template<typename T>
class A {
    // makeA should become a friend
    A() {}
};

template<typename T, typename U>
A<T> makeA(const U & u) {
    (void) u;
    return A<T>();
}

int main() {
    makeA<double>(3);
    return 0;
}

但是我不能让makeA成为A的朋友。这可能吗?什么是正确的语法?

【问题讨论】:

  • 首先你不应该将 A() -->构造函数设为私有
  • 你在问什么“正确的语法”?这让makeA 成为朋友?你的问题到底是什么?你想和它交朋友吗?或者不加好友,你想访问私有构造函数?
  • @Nawaz 您发布的答案正是我想要的。在友谊声明中,我使用makeA(U) 而不是makeA(const U &amp;)。谢谢!
  • @Nawaz 我可以访问私有构造函数而不使其成为朋友吗???
  • @Shan Uhm 请问什么?这可能就是为什么要使用friend 函数进行构造的原因?!

标签: c++ c++11 friend


【解决方案1】:

你可以把friend设为:

template<typename T>
class A
{

   template<typename TT, typename U>
   friend A<TT> makeA(const U & u) ;

};

您甚至可以在类中定义friend 函数。

【讨论】:

    【解决方案2】:

    虽然解决办法

    template <typename T>
    class A
    {
    
       template<typename TT, typename U>
       friend A<TT> makeA(const U & u) ;
    
    };
    

    工作,它的副作用是makeA&lt;int, int&gt;不仅是A&lt;int&gt;的朋友,而且还是A&lt;double&gt;A&lt;char&gt;等的朋友。在其他工作中,makeA&lt;TT, U&gt;是每个A&lt;T&gt;A&lt;T&gt;给予的友谊太广了。

    您可以通过使用不同的设计来限制这一点。

    template <typename T> class AMaker;
    
    template <typename T>
    class A
    {
       A() {}
    
       friend class AMaker<T>;
    };
    
    template<typename T> class AMaker
    {
       public:
          template <typename U>
             static A<T> make(const U & u)
             {
                (void) u;
                return A<T>();
             }
    };
    
    int main()
    {
       A<double> x = AMaker<double>::make(3);
       return 0;
    }
    

    这里,A&lt;T&gt; 授予的友谊仅限于AMaker&lt;T&gt;AMaker&lt;int&gt;A&lt;int&gt; 的朋友,但不是 A&lt;double&gt; 的朋友。

    【讨论】:

      【解决方案3】:

      我对你的程序做了一些改动 模板

      class A {
          // makeA should become a friend
      
          A() {} 
          public:
          template<typename S,typename U>
          friend A<S> makeA(const U & u); //this is correct way to makeA friend of A
      };
      
      template<typename T, typename U>
      A<T> makeA(const U & u) {
          (void) u;
          return A<T>();
      }
      
      int main() {
        makeA<double>(3);
          return 0;
      }
      

      现在它可以工作了,你可以在这里看到 http://ideone.com/1F1l3o

      【讨论】:

      • @Shan 我的反对意见是在这个问题上写的。
      • friend 函数不需要public
      • 不会造成任何危害,对吧? 臃肿、不可读的代码(如果这样不会造成危害,那么就可以了)。 知道这很好,但其他研究人员应该如何阅读?
      【解决方案4】:

      这里是不使用friend的解决方案:

      template<class T>
      class A {
          A() {}
      public:
          template<class U> static A make(U && u) {
              return A();
          }
      };
      
      template<class T, class U>
      A<T> makeA(U && u) {
          return A<T>::template make<U>(std::forward<U>(u));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-30
        • 1970-01-01
        • 1970-01-01
        • 2021-10-25
        • 2021-12-06
        • 1970-01-01
        相关资源
        最近更新 更多