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

john01dav

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

#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 ++包装器可能已经做到了这一点,但是为了更好地学习Vulkan,我现在正在使用C API。我在使用C API时遇到的此问题显示了我要修复的C ++知识方面的空白。

贾罗德42

主要问题

template<typename T, typename U, typename ... Args>
void functionTemplate(U (*)(Args..., int, int), Args...);

T是不可推论的,你不提供它。

第二个问题是推导可变参数模板的规则是“有限的”,Args并且未如预期那样推导U (*)(Args..., int, T)它被推导出为空包(这导致未推论/匹配T)。FirstArgs还与Args推断为[ concst char*]的秒数冲突

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章