テンプレートのtypename引数への参照を渡す方法


16

参照を引数としてテンプレートのtypename引数に渡す方法はありますか?たとえば、intへの参照を渡すために、intを渡す代わりにそうします。

template <typename T>
struct Foo
{
    Foo(T arg) : ptr(arg) {}
    T ptr;
};

int main() 
{
    int* a = new int(6);
    Foo<decltype(a)> foo1(a); // ptr is a copy of a pointer
    Foo<decltype(&a)> foo1(&a); // ptr seems to be a pointer to a pointer
}

「ptr」メンバーをクラスでT&にすることでポインターへの参照にできることはわかっていますが、これはテンプレート引数に渡された引数から実行できるかどうか疑問に思っていました。


decltypeタイトルをそのまま取ることができるので、にとどまりたいと思いますFoo<int*&>
idclev 463035818

回答:


19

あなたが探していFoo<decltype(a) &> foo1(a)ます。

(この特定のケースで機能する)よりあいまいな代替策はFoo<decltype((a))> foo1(a)です。


1
ああ、理にかなっている、ありがとう。decltype((a))の二重括弧はどのように機能しますか?それはどのようにそれを参照にしますか?
ゼブラフィッシュ

2
@Zebrafish基本的にはdecltype、変数名か何か(任意の式)を指定するかによって動作が異なります。decltype(a)変数の型を返しますa(単に変数名を付けただけなので)。decltype((a))一方、あなたの種類与える (a)(また、あるint式の値のカテゴリを示す追加基準らしで)。[1/2]
HolyBlackCat

(a)(およびa)は左辺値であり、&(xvalueはで表され&&、prvalueはタイプをまったく変更しません)で示されます。式には参照decltype型がないため、型に参照性を追加できるという事実は、競合を引き起こしません。[2/2]
HolyBlackCat

3

前の回答の代わりに、std :: reference_wrapperを使用できます

std :: reference_wrapperは、コピー可能な割り当て可能なオブジェクトで参照をラップするクラステンプレートです。通常は参照を保持できない標準コンテナ(std :: vectorなど)内に参照を格納するメカニズムとしてよく使用されます。

#include <functional>

template <typename T>
struct Foo
{
  Foo(T arg) : ptr(arg)
  {
  }
  T ptr;
};

int main()
{
  int* a = new int(6);

  Foo<std::reference_wrapper<int*>> foo1(std::ref(a));
  foo1.ptr[0] = 1;  // ok

  // This also works
  int* b = new int(6);
  Foo<std::reference_wrapper<decltype(b)>> foo2(std::ref(b));
  // and this too
  foo1 = foo2;

  // Or, if you use c++17, even this
  Foo foo3(std::ref(b));
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.