39

クラス テンプレート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};
}

私が望むのは、make_obj関数 aを宣言friendして を作成できるようにすることObjですが、他の誰も作成できません (コピー ctor を使用する場合を除く)。


を含むいくつかの友人宣言を試しました

friend Obj make_obj(T&);

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

後者は、クラスの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");
             ^

例としてやろうとしていmake_obj("hello");ます。

の値コンストラクターmake_objへのアクセスのみを許可するにはどうすればよいですか?Obj

4

2 に答える 2

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;
}

https://ideone.com/3k86gx

于 2016-12-28T10:34:09.497 に答える