Reputation: 13876
Is there a way to pass a reference as an argument to a template typename argument? I mean so instead of passing an int, for example, to pass a reference to an 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
}
I know I can make the 'ptr' member be a reference to a pointer by making it T& in the class, but I was wondering if this can be done from argument that's passed to the template argument.
Upvotes: 16
Views: 2614
Reputation: 10982
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));
}
Upvotes: 3
Reputation: 96246
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)
.
Upvotes: 19