我的基于可变参数模板的包装函数有什么问题?

What is wrong with my variadic-template-based wrapper function?

我目前正在开发一个程序,我想在其中将一些 Vulkan 函数包装在一个更易于使用的可变参数模板中¹。然而,当我尝试这样做时,我遇到了编译器错误(我在 Linux 上尝试了 GCC 和 clang,同时使用了 C++14 和 C++17 标志)。以下玩具示例演示了类似结构的错误:

#include <iostream>

int exampleFunction(const char *str, int a, int b){ //a const char* is used instead of std::string in order to avoid worrying about the fact that std::string is a class with overridden copying and move semantics
    std::cout << str << ": " << a << std::endl;
    std::cout << str << ": " << b << std::endl;
    return a+b; //to avoid non-void return type, as is the case in my real program
}

template<typename T, typename U, typename ... Args>
void functionTemplate(U (*function)(Args...,int,T), Args... args){
    function(args..., 1, 2);
}

int main() {
    functionTemplate(&exampleFunction, "label")
    return 0;
}

当我在 clang 8.0.1 中将此程序编译到 x86_64-pc-linux-gnu 目标时,出现以下错误:

<path redacted>/main.cpp:15:5: error: no matching function for call to 'functionTemplate'
    functionTemplate(&exampleFunction, "label")
    ^~~~~~~~~~~~~~~~
<path redacted>/main.cpp:10:6: note: candidate template ignored: could not match 'int' against 'const char *'
void functionTemplate(U (*function)(Args...,int,T), Args... args){

我希望程序能够正确编译并输出以下内容:

label: 1
label: 2

为什么这没有发生?一个好的答案将提供大量理论来解释原因,而不仅仅是如何解决它。我问这个问题主要是为了修复我的 C++ 知识中的漏洞,我不知道为什么这不起作用。在实际程序中除了这种构造风格还有其他选择。

¹:Vulkan 上的 C++ 包装器可能已经这样做了,但我现在正在使用 C API 以便更好地学习 Vulkan。我在使用 C API 时遇到的这个问题表明我想要修复的 C++ 知识存在差距。

的主要问题
template<typename T, typename U, typename ... Args>
void functionTemplate(U (*)(Args..., int, int), Args...);

就是T不可推,你你不提供

第二个问题是可变参数模板的推导规则是"limited" 并且 Args 未按 U (*)(Args..., int, T) 的预期推导。它被推断为空包(导致非 deduced/matching T)。第一个 Args 也与第二个 Args 冲突,推导为 [concst char*].