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.
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
For normal template parameters (neither template template parameters, or nor non-type template parameters), you can use either class or typename interchangeably, so these two mean exactly the same thing to the compiler: template <class foo> template <typename foo>
You cannot give default arguments to the same template parameters in different declarations in the same scope. The compiler will not allow the following example: template<class T = char> class X; template<class T = char> class X { };
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
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));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With