C++ 声明模板类的模板友元函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18792565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:12:53  来源:igfitidea点击:

declare template friend function of template class

c++templatesc++11friend

提问by Ryan Haining

I have a class template Objand a function template make_obj. Objhas a privatesingle constructor defined, which takes a reference to its templated type to bind to.

我有一个类模板Obj和一个函数模板make_obj。 定义Objprivate一个构造函数,该构造函数接受对其要绑定到的模板化类型的引用。

template <typename T>
class Obj {
  private:
    T& t;
    Obj(T& t)
        : t{t}
    { }
};

template <typename T>
Obj<T> make_obj(T& t) { 
    return {t};
}

What I want is to declare the make_objfunction a friendso that it can create Obj's, but no one else can (except via the copy ctor).

我想要的是声明make_obj函数 afriend以便它可以创建Obj's,但没有其他人可以(通过复制 ctor 除外)。



I have tried several friend declaration including

我尝试了几个朋友声明,包括

friend Obj make_obj(T&);

and

template <typename T1, typename T2>
friend Obj<T1> make_obj(T2&);

The latter being a less than desirable attempt at making all template instantiations of make_objfriends of the Objclass. However in both of these cases I get the same error:

后者是make_objObj类的朋友的所有模板实例化的不太理想的尝试。但是,在这两种情况下,我都会遇到相同的错误:

error: calling a private constructor of class 'Obj<char const[6]>'
    return {t};
           ^

note: in instantiation of function template specialization
      'make_obj<const char *>' requested here
    auto s = make_obj("hello");
             ^

trying to do make_obj("hello");for example purposes.

试图做make_obj("hello");的例子目的。

How can I allow only make_objaccess to Obj's value contructor?

如何只允许make_obj访问Obj的值构造函数?

回答by Daniel Frey

You need a few forward declarations:

您需要一些前向声明:

template <typename T>
class Obj;

template <typename T>
Obj<T> make_obj(T t);

template <typename T>
class Obj {
private:
    T & t;
    Obj (T & t) : t(t) { }
    Obj() = delete;

    friend Obj make_obj<T>(T t);
};

template <typename T>
Obj<T> make_obj(T t) { 
    return Obj<T>(t);
}

live example

活生生的例子

And BTW: I don't think you really want T & t;for your class' member variable. Probably T t;is a better choice ;)

顺便说一句:我不认为你真的想要T & t;你班级的成员变量。可能T t;是更好的选择;)

回答by Curious

With the automatic return type syntax, you only need to forward declare the function and everything works. Here is an example

使用自动返回类型语法,您只需要向前声明函数,一切正常。这是一个例子

template <typename T>
auto make_obj(T t);

template <typename T>
class Obj {
private:
    T & t;
    Obj (T & t) : t(t) { }
    Obj() = delete;

    friend auto make_obj<T>(T t);
};

template <typename T>
auto make_obj(T t) {
    return Obj<T>{t};
}

int main() {
    make_obj(1);
    return 0;
}

https://ideone.com/3k86gx

https://ideone.com/3k86gx