In the gem5 codebase, there is a class that follows this pattern (the following code is a minimal example that recreates the issue in question):
template <size_t Size>
class VecRegContainer;
template <typename VecElem, size_t NumElems, bool Const>
class VecRegT
{
static constexpr size_t Size = sizeof(VecElem) * NumElems;
public:
using Container = typename std::conditional<Const,
const VecRegContainer<Size>,
VecRegContainer<Size>>::type;
private:
Container& container;
public:
const VecElem& operator[](size_t idx) const
{
return container.template raw_ptr<VecElem>()[idx];
}
};
template <size_t Size>
class VecRegContainer
{
std::array<uint8_t, Size> container;
public:
template <typename Ret>
const Ret* raw_ptr() const { return (const Ret*)container.data(); }
};
Now, this compiles just fine. However, my confusion is this: why do we need the template
keyword in container.template raw_ptr<VecElem>()[idx];
? I read this stack overflow answer but I don't see how it maps to my example.
In the function, we know that VecElem
is a type, so it should be clear that raw_ptr
is a template member function of the object container
. However, if I remove the template
keyword, the code fails to compile with the following error:
error: use 'template' keyword to treat 'raw_ptr' as a dependent template name
return container.raw_ptr<VecElem>()[idx];
^
template
1 error generated.
What exactly is raw_ptr
"dependent" on? Isn't it clear from context?