调用函数模板时出错"No matching function"

"No matching function" error with call to function template

本文关键字:No function matching 出错 函数模板 调用      更新时间:2023-10-16

我想使用GLM矩阵头文件库为我的c++图形项目创建一个转换矩阵。为了进行测试,我编写了以下简单代码:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
int main()
{
    glm::mat4 projection_matrix = glm::perspective(45, 1.5, 0.1, 100);
    return 0;
}
但是,我收到以下编译错误:
/home/Karnivaurus/Projects/GLMTest/src/main.cpp:6: error: no matching function for call to 'perspective(int, double, double, int)'
     glm::mat4 projection_matrix = glm::perspective(45, 1.5, 0.1, 100);
                                                                     ^
                                                                     ^

紧随其后:

candidate is:
/usr/local/include/glm/gtc/matrix_transform.inl:218: template<class T> glm::detail::tmat4x4<T, (glm::precision)0u> glm::perspective(const T&, const T&, const T&, const T&)
  GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> perspective
                                                  ^
在提供的源代码中查看这个函数的实现,我可以看到:
template <typename T>
    GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> perspective
    (
        T const & fovy,
        T const & aspect,
        T const & zNear,
        T const & zFar
    )
    {
    //
    // The implementation ..........
    // .....
    // .....
    //
    }

我对c++中的模板不是特别熟悉。有人能给我解释一下这个错误吗?

您可以将示例简化为:

template <typename T>
void foo(const T&, const T& )
{ }
int main(){
    foo(45, 1.0); // error: no matching function for call to foo(int, double)
}

这是因为当模板演绎发生时,它将T演绎为第一个参数的int,将double演绎为第二个参数,但是只有一个T,所以它必须是一致的!模板演绎不会发生转换(这里intdouble可以相互转换并不重要),所以一旦我们得到不一致的类型,演绎就会失败——而且因为只有一个foo,所以没有其他的重载可以依靠。

解决方案是确保类型相同:

foo(45.0, 1.0); // calls foo<double>
foo(45, 1);     // calls foo<int>

或者显式指定T是什么:

foo<double>(45, 1.0);  // calls foo<double>, explicitly

在后一种情况下,自指定T以来没有发生演绎,这相当于调用了:

void foo(const double&, const double& );

所以第一个参数被转换为double

在声明函数时,必须推导出它的所有参数都是相同类型的T。在您的调用中,您提供了两个int和两个double。它们不相同,因此实例化失败。

将呼叫改为:

glm::mat4 projection_matrix = glm::perspective(45.0, 1.5, 0.1, 100.0);

您还可以显式指定类型以启用转换:

glm::mat4 projection_matrix = glm::perspective<double>(45, 1.5, 0.1, 100);

函数模板用一个模板形参定义它的所有实参。您为参数传递了不同的类型,int用于第一个和最后一个参数,double用于中间参数。

修复方法是一致地对所有参数使用double s:

glm::mat4 projection_matrix = glm::perspective(45.0, 1.5, 0.1, 100.0);