什么是可变参数函数模板重载优先规则?

What is the variadic function template overloading precedence rule?

我正在使用通用递归格式的可变参数函数模板,每当我处理向量时,我都需要更改函数的行为。 如果函数模板不是可变的,重载效果很好,但是对于可变函数模板,解压参数包时重载分辨率似乎会改变。

下面的一些代码可以更好地解释我的意思。

#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;
}

complexfun(x1, vint) 的执行中,我们应该有 complexfun(vint),但它的行为并不像“独立”调用 complexfun(vint)

非常感谢任何关于为什么会出现这种情况以及如何解决它的帮助!

您需要在应该使用它的函数之前声明 template<typename T> void complexfun(std::vector<T>)

只需调换这些函数模板的顺序即可:

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