To start, I have something like this:
class Test {
std::vector<int> a, b;
void caller(...) { callee(...); }
void callee(...) { /* Do stuff with 'a' */ }
}
What I wanted is to have a function that does exactly the same as callee
but for vector b
. To do this there are two obvious solutions:
a
or b
as argument. However, callee
is a recursive function that can go for hundreds of calls, and passing the vectors as arguments would just be unnecessary overhead.callee
and use vector b
, which would be the best alternative, despite the fact that callee
is quite a long function and I would have a lot of duplicate code.Out of curiosity, I went looking for the templates part and I noticed that can be used for
lvalue reference type
pointer type
pointer to member type
So I tried to do this:
class Test {
std::vector<int> a, b;
void caller(...) { callee<a>(...); }
template <std::vector<int> &x> void callee(...) { /* Do stuff with 'x' */ }
}
but I get
error: use of ‘this’ in a constant expression
Is there any way to achieve this either with a reference or a pointer?
By the way, what I want can be seen as a function-scoped #define
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.
Pass-by-reference means to pass the reference of an argument in the calling function to the corresponding formal parameter of the called function. The called function can modify the value of the argument by using its reference passed in. The following example shows how arguments are passed by reference.
A template has only one type, but a specialization is needed for pointer, reference, pointer to member, or function pointer types. The specialization itself is still a template on the type pointed to or referenced.
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.)
Arrays and even tuples, but no love for good old pointers-to-members ?
class Test {
std::vector<int> a, b;
void caller(/*...*/) { callee<&Test::a>(/*...*/); }
template <std::vector<int> Test::*vec>
void callee(/*...*/) { /* Do stuff with `(this->*vec)` */ }
};
You cannot use a reference to a data member as a template argument: templates are compile-time, and the value of this
is not known until runtime. In other words, you'd need a separate instantiation (separate binary code) for each runtime object of type Test
.
What you can do is replace a
and b
with an array, and templatise callee
by index into this array:
class Test {
std::array<std::vector<int>, 2> ab;
void caller(...) { callee<0>(...); }
template <size_t idx>
void callee(...) { /* Do stuff with 'ab[idx]' */ }
}
This way, you get only two instantiations of callee
(one for 0
and one for 1
), with the indexing done (or at least doable) at compile time.
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