Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template parameter name hiding

I got recently bitten by (simplified)

struct Base {
    typedef char T;
};

template<typename T>
struct Foo : Base {
    T x[50];  // This is Base::T, not the template parameter
};

In other words a class member name hides a template parameter (even if coming from a base class, thus not being totally evident in the local context).

Making some experiment I found however that:

struct Base {
    typedef char T;
};

template<typename T, typename B>
struct Foo : B {
    T x[50];  // This T is the template parameter,
              // even passing Base as B
};

What is the rationale (if any) behind this apparently absurd rule?

The only way out I can think to is to give ugly template parameter names and also means that it's impossible to write safely a template without using reserved names (as class used in the template could clash parameter names... note that a lot of C++ code uses uglyfied names for private members).

PS: I didn't dig in the standard about the issue but both g++ and clang++ agree on this behavior so I don't think it's a bug.

PPS: In the real code the template parameter being hidden was named tid, and was an integer and not a type. -Wall was not enough to notifiy about the hiding and I discovered it after a couple of hours of debugging with valgrind.

like image 688
6502 Avatar asked Mar 31 '15 07:03

6502


1 Answers

This rule (specified in [temp.local]/9) is subject of an open core language issue created over 11 years ago - core issue #459. The CWG discussed this thoroughly. About the intent, Mike Miller mentions that

The rationale for the current specification is really very simple:

  • “Unless redeclared in the derived class, members of a base class are also considered to be members of the derived class.” (10 [class.derived] paragraph 2)

  • In class scope, members hide nonmembers.

That's it. Because template parameters are not members, they are hidden by member names (whether inherited or not). I don't find that “bizarre,” or even particularly surprising.

Rationale:

We have some sympathy for a change, but the current rules fall straightforwardly out of the lookup rules, so they're not “wrong.” Making private members invisible also would solve this problem. We'd be willing to look at a paper proposing that.[..]
The CWG decided not to consider a change to the existing rules at this time without a paper exploring the issue in more detail.

Unfortunately no such paper has been written yet, and so the rule persists until today.

like image 78
Columbo Avatar answered Oct 25 '22 03:10

Columbo