0

I am new to templates, and I have been forced to use one in a function while the underlying class used is not a template. A very simple case where my problem occurs is the following :

//test.h

struct Top
{
    struct Bottom
    {
    };

    Bottom bot;
};


//test.cpp

void without_template(Top content)
{
    Top::Bottom bot = content.bot;
}

template<typename T>
void with_template(T content)
{
    // Uncomment to get an error :
    // T::Bottom bot = content.bot; 
}

template<typename T>
void with_template_2(T content)
{
    auto bot = content.bot; 
}

(Currently, my code works using "auto", but I would like to avoid using it like that, this looks really unsafe.) (Also, in the actual code, everything is in .h, but the same thing occurs.)

The error is C2760 : syntax error: expected ";" after "T" ; followed by C7510 : 'Bottom' : a dependent type name has to be preceeded by 'type name' (sorry for not quoting it exactly, my compiler is in French)

I though templates were basically just inlining the type name, but apparently not. So what is going on here ? In particular, there is an error even if "with_template" is never called...

My best guess is that the syntax "T::..." is simply not supported, but I don't see why that would be the case.

Is there an elegant fix ? (appart from making the underlying class a template, which would just propagate the use of templates in my code)

(I also tried "using namespace", but it doesn't seem to work.)

  • Your question has an excellent answer [here](https://stackoverflow.com/a/613132/2144408). In your specific case, it boils down to: Go to the line of the error; add a specific typename for the variable, referring to 'T::Bottom' with 'typename ' at the start. For example; 'using B = typename T::Bottom'. This is to indicate that Bottom is a typename within T, not a static constant. – TamaMcGlinn Apr 08 '20 at 09:00

1 Answers1

0

In a template function, the template parameters are unknown when the compiler parses it. That means that anything that depends on a template parameter is basically also unknown. Because the compiler can't know what Bottom is, you need to tell it what to expect.

If you don't tell it anything the compiler will assume it's a member or member function, this it will figure out by itself from context. But if it's a type, you need to explicitly say so.

template<typename T>
void with_template(T content)
{
    typename T::Bottom bot = content.bot;
     // ^-- typename here tells the compiler that Bottom is a type
}

More information on dependent names.

super
  • 12,335
  • 2
  • 19
  • 29