Come passare un riferimento a un argomento typename del modello


16

Esiste un modo per passare un riferimento come argomento a un argomento del modello typename? Intendo dire invece di passare un int, ad esempio, per passare un riferimento a un 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
}

So di poter fare in modo che il membro 'ptr' sia un riferimento a un puntatore rendendolo T & nella classe, ma mi chiedevo se ciò potesse essere fatto dall'argomento passato all'argomento template.


Suppongo che tu voglia restare decltype, perché prendendo il titolo letteralmente potresti semplicemente scrivereFoo<int*&>
idclev 463035818

Risposte:


19

Stai cercando Foo<decltype(a) &> foo1(a).

Un'alternativa più oscura (che funziona in questo caso specifico) è Foo<decltype((a))> foo1(a).


1
Ah, ha senso, grazie. Come funzionano le doppie parentesi in decltype ((a))? Come lo rende un riferimento?
Zebrafish

2
@Zebrafish Fondamentalmente, decltypefunziona in modo diverso a seconda che tu gli dia un nome variabile o qualcos'altro (un'espressione arbitraria). decltype(a)restituisce il tipo di variabile a(perché gli hai semplicemente dato un nome di variabile). decltype((a))d'altra parte, ti dà il tipo di espressione (a) (che è anche int), con un riferimento aggiunto che indica la categoria di valore dell'espressione. [1/2]
HolyBlackCat

(a)(così come a) è un valore, che è indicato da &(i valori x sono rappresentati da &&, i valori non cambiano affatto il tipo). Poiché le espressioni non hanno mai tipi di riferimento, il fatto che decltypepossa aggiungere riferimenti al tipo non può causare conflitti. [2/2]
HolyBlackCat

3

In alternativa alla risposta precedente, è possibile utilizzare std :: reference_wrapper

std :: reference_wrapper è un modello di classe che avvolge un riferimento in un oggetto copiabile e assegnabile. Viene spesso utilizzato come meccanismo per memorizzare riferimenti all'interno di contenitori standard (come std :: vector) che normalmente non possono contenere riferimenti.

#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));
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.