带有附加参数的模板工厂函数:友谊问题

Template factory function with additional args: friendship issue

我正在编写一段如下所示的代码:

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的朋友。这可能吗?什么是正确的语法?

您可以将其 friend 设为:

template<typename T>
class A
{

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

};

您甚至可以在 class.

中定义 friend 函数

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

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

虽然解决方案

template <typename T>
class A
{

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

};

有效,它的副作用是 makeA<int, int> 不仅是 A<int> 的朋友,也是 A<double>A<char> 等的朋友。在其他工作,makeA<TT, U> 是每个 A<T> 的朋友。 A<T> 授予的友谊太广泛了。

您可以使用不同的设计来限制它。

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<T>授予的友谊仅限于AMaker<T>AMaker<int>A<int> 的朋友,但不是 A<double> 的朋友。

这里有一个不使用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));
}