I want to use the GLM matrix header-only library to create a transformation matrix for my C++ graphics project. To test this out, I wrote the following simple code:
#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;
}
However, I receive the following compilation error:
/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);
^
^
Followed by:
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
^
Looking at the implementation of this function in the provided source code, I can see:
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 ..........
// .....
// .....
//
}
I'm not particularly familiar with templates in C++. Can anybody explain this error to me please?
You can simplify your example to:
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)
}
That is because when template deduction happens, it deduces T
as int
for the first argument and double
for the second, but there is only one T
so it has to be consistent! No conversions will happen for template deduction (it doesn't matter here that int
and double
are convertible to each other), so once we get inconsistent types, deduction fails - and since there is only one foo
, there's no other overload to fall back on.
The solutions are either to ensure that the types are the same:
foo(45.0, 1.0); // calls foo<double>
foo(45, 1); // calls foo<int>
Or to explicitly specify what T
is:
foo<double>(45, 1.0); // calls foo<double>, explicitly
In the latter case, no deduction occurs since we specified T
, and this is equivalent to having called:
void foo(const double&, const double& );
so the first argument is just converted to double
.