Home > database >  What is the variadic function template overloading precedence rule?
What is the variadic function template overloading precedence rule?

Time:04-01

I'm using variadic function templates in the common recursive format and I need to change the behaviour of the function whenever I'm handling a vector. If the functions templates were not variadic, overloading works well, but with variadic function templates, the overloading resolution seems to change when unpacking the argument pack.

Below some code to explain better what I mean.

#include <iostream>
#include <vector>

template<typename T>
void complexfun(T x) {
    std::cout << "1 end" << std::endl;
}

template<typename T, typename... Args>
void complexfun(T x, Args... args) {
    std::cout << "1 ";
    complexfun(args...);
}

template<typename T>
void complexfun(std::vector<T> x) {
    std::cout << "2 end" << std::endl;
}

template<typename T, typename... Args>
void complexfun(std::vector<T> x, Args... args) {
    std::cout << "2 ";
    complexfun(args...);
}

int main() {
    std::vector<int> vint = {2, 3, 4};
    float x1 = 9.4;
    
    complexfun(vint); // output: 2 end -> OK
    complexfun(vint, x1); // output: 2 1 end -> OK
    complexfun(x1, vint); // output: 1 1 end -> WRONG: need 1 2 end
    
    return 0;
}

In the execution of complexfun(x1, vint) we should have complexfun(vint), but it does not behave as the "standalone" call complexfun(vint).

Any help on why this is the case and how to fix it is greatly appreciated!

CodePudding user response:

You need to declare template<typename T> void complexfun(std::vector<T>) before the function that is supposed to be using it.

Just swap the order of those function templates so you get:

template<typename T>                   // this function template
void complexfun(std::vector<T>) {      
    std::cout << "2 end" << std::endl;
}

template<typename T, typename... Args> // ...before this function template
void complexfun(T, Args... args) {     
    std::cout << "1 ";
    complexfun(args...);
}

Demo

  • Related