我想使用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 ++中的模板并不是特别熟悉。有人可以向我解释这个错误吗?
答案 0 :(得分:2)
您可以将示例简化为:
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
可以相互转换并不重要),所以一旦我们得到不一致的类型,推论就会失败 - 因为只有一个{ {1}},没有其他重载可以依赖。
解决方案要么确保类型相同:
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& );
。
答案 1 :(得分:2)
声明函数时,必须推导出所有参数的类型double
。在通话中,您提供了两个T
和两个int
。它们不相同,因此实例化失败。
将您的电话改为:
double
您还可以明确指定类型以启用转化:
glm::mat4 projection_matrix = glm::perspective(45.0, 1.5, 0.1, 100.0);
答案 2 :(得分:1)
函数模板使用单个模板参数定义其所有参数。您为参数传递了不同的类型,int
表示第一个和最后一个,double
表示中间参数。
修复方法是始终对所有参数使用double
:
glm::mat4 projection_matrix = glm::perspective(45.0, 1.5, 0.1, 100.0);