Как передать ссылку на аргумент typename шаблона - PullRequest
16 голосов
/ 25 марта 2020

Есть ли способ передать ссылку в качестве аргумента в аргумент типового имени шаблона? Я имею в виду, что вместо передачи 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 & in класс, но мне было интересно, если это можно сделать из аргумента, который передается в аргумент шаблона.

Ответы [ 2 ]

19 голосов
/ 25 марта 2020

Вы ищете Foo<decltype(a) &> foo1(a).

Более неясная альтернатива (которая работает в этом конкретном случае c) - Foo<decltype((a))> foo1(a).

3 голосов
/ 25 марта 2020

В качестве альтернативы предыдущему ответу вы можете использовать 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));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...