Skip to content

Commit e5f8a6b

Browse files
committed
Add template keyword to fix dependent name errors
Clang and GCC complained about this, and it's indeed needed (see e.g. https://eigen.tuxfamily.org/dox/TopicTemplateKeyword.html). MSVC accepts it without template keyword, but it's non-standard C++. Basically, the object that we call the templated function on (head<>() or cast<>()) is itself a templated type. Because we don't know at compile time what that first templated type is, the compiler can't know what the function is that we call on it (i.e. it could be a type or operator<()). So we need the "template" keyword to tell the compiler that it's a templated function. One way to avoid this would be to declare a template at namespace scope, like std::tuple: It has an associated get function template that is declared in the std namespace instead of being a class member, so we can do std::get<i>(t) instead of t.template get<i>(). However, that's not really a good solution here I think. There's also nothing wrong with using `template` here, it just makes the code a bit more difficult to read.
1 parent b4f89ce commit e5f8a6b

File tree

2 files changed

+21
-11
lines changed

2 files changed

+21
-11
lines changed

include/eos/fitting/ceres_nonlinear.hpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ struct PerspectiveProjectionLandmarkCost
168168
Eigen::Map<const Eigen::Vector3<T>> translation(camera_translation);
169169

170170
Eigen::Matrix4<T> model_view_mtx = Eigen::Matrix4<T>::Identity();
171-
model_view_mtx.block<3, 3>(0, 0) = rotation.toRotationMatrix();
172-
model_view_mtx.col(3).head<3>() = translation;
171+
model_view_mtx.template block<3, 3>(0, 0) = rotation.toRotationMatrix(); // dependent name
172+
model_view_mtx.col(3).template head<3>() = translation; // dependent name
173173

174174
// Todo: use get_opencv_viewport() from nonlin_cam_esti.hpp.
175175
const Eigen::Vector4<T> viewport(T(0), T(image_height), T(image_width),
@@ -296,8 +296,8 @@ struct VertexColorCost
296296
Eigen::Map<const Eigen::Vector3<T>> translation(camera_translation);
297297

298298
Eigen::Matrix4<T> model_view_mtx = Eigen::Matrix4<T>::Identity();
299-
model_view_mtx.block<3, 3>(0, 0) = rotation.toRotationMatrix();
300-
model_view_mtx.col(3).head<3>() = translation;
299+
model_view_mtx.template block<3, 3>(0, 0) = rotation.toRotationMatrix(); // dependent name
300+
model_view_mtx.col(3).template head<3>() = translation; // dependent name
301301

302302
// Todo: use get_opencv_viewport() from nonlin_cam_esti.hpp.
303303
const Eigen::Vector4<T> viewport(T(0), T(image.height()), T(image.width()),
@@ -385,9 +385,12 @@ Eigen::Vector3<T> get_shape_at_point(const eos::morphablemodel::PcaModel& shape_
385385
{
386386
// Computing Shape = mean + shape_basis*shape_coeffs + blendshapes*blendshape_coeffs:
387387
const Eigen::Vector3f mean = shape_model.get_mean_at_point(vertex_id);
388-
const Eigen::Vector3<T> shape_vector =
389-
shape_model.get_rescaled_pca_basis_at_point(vertex_id).leftCols(shape_coeffs.size()).cast<T>() *
390-
shape_coeffs;
388+
// Note: We seem to have a dependent name here, so we need 'template', to help the compiler that 'cast<T>'
389+
// is a template.
390+
const Eigen::Vector3<T> shape_vector = shape_model.get_rescaled_pca_basis_at_point(vertex_id)
391+
.leftCols(shape_coeffs.size())
392+
.template cast<T>() *
393+
shape_coeffs;
391394
Eigen::Vector3<T> expression_vector(T(0.0), T(0.0), T(0.0));
392395
for (std::size_t i = 0; i < blendshape_coeffs.size(); i++)
393396
{
@@ -412,9 +415,12 @@ Eigen::Vector3<T> get_vertex_color_at_point(const eos::morphablemodel::PcaModel&
412415
Eigen::Map<const Eigen::VectorX<T>> color_coeffs)
413416
{
414417
const Eigen::Vector3f mean = color_model.get_mean_at_point(vertex_id);
415-
const Eigen::Vector3<T> color_vector =
416-
color_model.get_rescaled_pca_basis_at_point(vertex_id).leftCols(color_coeffs.size()).cast<T>() *
417-
color_coeffs;
418+
// Note: We seem to have a dependent name here, so we need 'template', to help the compiler that 'cast<T>'
419+
// is a template.
420+
const Eigen::Vector3<T> color_vector = color_model.get_rescaled_pca_basis_at_point(vertex_id)
421+
.leftCols(color_coeffs.size())
422+
.template cast<T>() *
423+
color_coeffs;
418424

419425
return Eigen::Vector3<T>(mean.cast<T>() + color_vector);
420426
};

include/eos/render/matrix_projection.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,11 @@ Eigen::Vector3<T> project(const Eigen::Vector3<T>& point_3d, const Eigen::Matrix
156156
projected_point.x() = projected_point.x() * T(viewport(2)) + T(viewport(0));
157157
projected_point.y() = projected_point.y() * T(viewport(3)) + T(viewport(1));
158158

159-
return projected_point.head<3>();
159+
// Note: We need the 'template' keyword, as we have a dependent name - 'T' is unknown when the compiler
160+
// parses this expression, so we need to tell it that 'head<3>()' is a template function (and not e.g. an
161+
// 'operator<' or something like that). We could alternatively rewrite this as:
162+
// 'return Eigen::Vector3<T>(projected_point.x(), projected_point.y(), projected_point.z());'
163+
return projected_point.template head<3>();
160164
};
161165

162166
} /* namespace render */

0 commit comments

Comments
 (0)