In the example below, I need to use the template
disambiguator in the line marked as #1, while it appears to be unnecessary in the other occurrence of a similar pattern. What does it make the difference?
#include <cstdint>
#include <utility>
#include <array>
#include <vector>
#include <ranges>
template<std::size_t n, typename TFn>
constexpr void constexpr_for(TFn Fn)
{
[&Fn]<std::size_t... i>(std::index_sequence<i...>)
{ (Fn(std::integral_constant<std::size_t, i>{}), ...); } (std::make_index_sequence<n>{});
}
struct TVertex {};
class TFace
{
public:
static constexpr std::size_t NVertex = 3u;
private:
std::array<TVertex const *, NVertex> VertexVec;
public:
template<std::size_t i>
TVertex const &GetVertex() const
{ return *std::get<i>(VertexVec); }
};
void f(std::vector<TFace> const &FaceVec)
{
for (auto const &[i, Face1] : std::views::zip(std::views::iota(0u), FaceVec))
constexpr_for<TFace::NVertex>([&](auto const j)
{
for (auto const &[_, Face2] : std::views::zip(std::views::iota(0u), FaceVec)
| std::views::drop(i + 1u))
constexpr_for<TFace::NVertex>([&](auto const k)
{
TVertex const &Vertex1 = Face1.GetVertex<j>();
TVertex const &Vertex2 = Face2.template GetVertex<k>(); // #1
});
});
}
I’m using GCC trunk. Here’s a Compiler Explorer link: https://godbolt.org/z/Kh6n6G4hW