"No matching function" 调用函数模板时出错
"No matching function" error with call to function template
我想使用 GLM 矩阵 header-only 库为我的 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++ 中的模板。有人可以向我解释这个错误吗?
函数模板的所有参数都使用一个模板参数定义。您正在为参数传递不同的类型,第一个和最后一个参数为 int
,中间参数为 double
。
解决方法是始终对所有参数使用 double
s:
glm::mat4 projection_matrix = glm::perspective(45.0, 1.5, 0.1, 100.0);
您可以将示例简化为:
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
所以它必须是一致的!模板推导不会发生转换(这里 int
和 double
可以相互转换并不重要),所以一旦我们得到不一致的类型,推导就会失败 - 因为只有一个 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);
我想使用 GLM 矩阵 header-only 库为我的 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++ 中的模板。有人可以向我解释这个错误吗?
函数模板的所有参数都使用一个模板参数定义。您正在为参数传递不同的类型,第一个和最后一个参数为 int
,中间参数为 double
。
解决方法是始终对所有参数使用 double
s:
glm::mat4 projection_matrix = glm::perspective(45.0, 1.5, 0.1, 100.0);
您可以将示例简化为:
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
所以它必须是一致的!模板推导不会发生转换(这里 int
和 double
可以相互转换并不重要),所以一旦我们得到不一致的类型,推导就会失败 - 因为只有一个 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);