Reputation: 33
my function looks like this
template<bool extra>
void func(int& arg1, const int arg2){
//a lot of code...
if (extra && arg2 > 0) ++arg1;
arg1 *= 10;
//a lot of code...
}
the problem is that when extra
is false
, arg2
is not used, but the function still requires it to be specified leading to unnecessary memory allocation for arg2
(you can check assembly output here). Is there any way to modify the function so that when extra
is false
, it only takes arg1
, avoiding memory allocation for arg2
in that case?
Upvotes: 1
Views: 150
Reputation: 3724
This kind of problem is commonly solved using template specialization, which unfortunately typically requires a wrapper struct instead of the plain functions.
Here's an example how that could work:
template<bool extra> // default case, only used for extra == false
struct Foo
{
static void run(int arg1) {
static_assert(extra == false);
//...
}
};
template<> //specialization, used for extra == true
struct Foo<true>
{
static void run(int arg1, const int arg2) {
//...
}
};
int main(){
Foo<false>::run(1);
Foo<true>::run(2, 3);
}
Depending on the desired API, you can sometimes create a wrapper function or use operator()
to avoid the slightly ugly ::run
calls.
In your specific example, where the signature of the two function version differs (because you don't expect arg2
for the extra == true
case), you could even get away with basic function overloading:
// In this simple case you could even remove the template argument completely
// and make the distinction purely based on the number of arguments.
// It all depends on what API you want to provide.
template<bool extra>
void func(int& arg1){
static_assert(extra == false);
}
template<bool extra>
void func(int& arg1, const int arg2){
static_assert(extra == true);
}
Note: If the template parameter should stay, a C++ 20 requires
clause or enable_if
guards instead of the static_assert
s would express the intent of the function signature more accurately, currently at the cost of arguably worse error messages.
Upvotes: 3