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

Rya*_*ing 31 c++ templates friend c++11

我有一个类模板Obj和一个函数模板make_obj. Obj有一个private构造函数定义,它引用其绑定的模板类型.

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

template <typename T>
Obj<T> make_obj(T& t) { 
    return {t};
}
Run Code Online (Sandbox Code Playgroud)

我想要的是声明make_obj函数a,friend以便它可以创建Obj,但没有其他人可以(除了通过复制ctor).


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

friend Obj make_obj(T&);
Run Code Online (Sandbox Code Playgroud)

template <typename T1, typename T2>
friend Obj<T1> make_obj(T2&);
Run Code Online (Sandbox Code Playgroud)

后者是完成该类make_obj朋友的所有模板实例化的不太理想的尝试Obj.但是在这两种情况下我都会得到同样的错误:

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");
             ^
Run Code Online (Sandbox Code Playgroud)

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

我怎样才能只允许make_obj访问Obj价值构造者?

Dan*_*rey 44

您需要一些前向声明:

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);
}
Run Code Online (Sandbox Code Playgroud)

实例

而BTW:我认为你真的不想要T & t;你的班级成员变量.可能T t;是一个更好的选择;)

  • 你去了所有9码然后丢球...朋友不应该是模板,而是模板*专业化*:) [只有`make_obj <A>`需要访问`Obj <A>`,不需要能够访问`make_obj <Z>`!] - 用于记录:`朋友Obj <T> make_obj <T>(T t);`而不是与模板交朋友 (6认同)

Cur*_*ous 6

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

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;
}
Run Code Online (Sandbox Code Playgroud)

https://ideone.com/3k86gx