How to pass a reference to a template typename argument
You're looking for Foo<decltype(a) &> foo1(a)
.
A more obscure alternative (which works in this specific case) is Foo<decltype((a))> foo1(a)
.
As an alternative to the previous answer, you can use std::reference_wrapper
std::reference_wrapper is a class template that wraps a reference in a copyable, assignable object. It is frequently used as a mechanism to store references inside standard containers (like std::vector) which cannot normally hold references.
#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));
}