Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ - Why is the 'template' keyword required here?

I have the following code:

template <typename TC>
class C
{
    struct S
    {
        template <typename TS>
        void fun() const
        {}
    };

    void f(const S& s)
    {
        s.fun<int>();
    }
};

// Dummy main function
int main()
{
    return 0;
}

When building this with both gcc 9.2 and clang (9.0), I'm getting a compilation error due to the template keyword being required for invoking fun. Clang shows:

error: use 'template' keyword to treat 'fun' as a dependent template name
        s.fun<int>();
          ^
          template 

I don't understand why the compiler thinks fun is a dependent name in the context of f, since f is not a template itself. If I change C to be a regular class instead of a template, the error goes away; however, I don't see why there should be an error in the first place since neither S nor f depend on TC.

Oddly enough, MSVC 19.22 compiles this just fine.


note

Before voting to close as dupe of Where and why do I have to put the "template" and "typename" keywords? please consider this is a special case where even if S is indeed a dependent name, in the context of f it would not be dependent if not for the fact that they are members of the current instantiation.

like image 583
Martin Avatar asked Feb 04 '20 17:02

Martin


People also ask

What is the use of template keyword?

Using the TEMPLATE keyword makes it clear to other programmers that the field or data structure is not intended to be used as a program variable. Even when you add a suffix such as _t to the name, the keyword makes it crystal-clear to other programmers.

Why do we use templates in C?

Templates are an important part of C++, as already mentioned, they allow you to develop functions or Classes that are type generic. You specify the type when you use them. You really should learn templates if, for no other reason, to understand boost and the standard template libraries.

What is the need of template?

Templates increase flexibility: Templates actually increase flexibility, they're easy to update, and they provide consistency across the project. They can be improved regularly to meet technological and instructional requirements as well as the client's needs. These are easily tracked and updated.

Is template a keyword in C?

The keywords typename and template are now not required anymore if the qualifier is a member of the current instantiation.


Video Answer


1 Answers

Consider:

template<typename T>
struct C
{
    struct S
    {
        int a = 99;
    };

    void f(S s, int i)
    {
        s.a<0>(i);
    }
};

template<>
struct C<long>::S
{
    template<int>
    void a(int)
    {}
};

int main()
{
    C<int>{}.f({}, 0); // #1
    C<long>{}.f({}, 0); // #2
}

s.a<0>(i) is parsed as an expression containing of two comparison operations < and >, and this is fine for #1 but fails for #2.

If this is changed to s.template a<0>(i) then #2 is OK and #1 fails. Thus the template keyword is never redundant here.

MSVC is capable of interpreting the expression s.a<0>(i) both ways within the same program. But this is not correct according to the Standard; each expression should have only one parse for the compiler to deal with.

like image 151
ecatmur Avatar answered Sep 19 '22 12:09

ecatmur