我目前正在开发一个程序,希望将一些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 ++知识方面的空白。
主要问题
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] 删除。
我来说两句