typedef and template parameter with same name

安稳与你 提交于 2021-01-26 22:29:36

问题


Why is that case incorrect (it's logical)

template <typename T>
struct Der: public Base
{
    typedef int T;
    T val;
};

, but that case is correct?

struct Base
{
    typedef int T;
};

template <typename T>
struct Der: public Base
{
    T val;
};

The Standard 14.6.1/7 says:

In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, for each base class which does not depend on a template-parameter (14.6.2), if the name of the base class or the name of a member of the base class is the same as the name of a template-parameter, the base class name or member name hides the template-parameter name (3.3.7).

Why is it not ambiguous in here?


回答1:


The first example is incorrect according to [temp.local]/6:

A template-parameter shall not be redeclared within its scope (including nested scopes).

However, in

template <typename T>
struct Der: public Base
{
    T val;
};

T is hidden by the name inherited from Base - as specified by your quote.

[..] if the name of the base class or the name of a member of the base class is the same as the name of a template-parameter, the base class name or member name hides the template-parameter name (3.3.7).

That is, the member val is of type int. Demo.




回答2:


In general, the standard tries to ensure that the meaning of a type in a given scope is the same.

If we pretend that the typedef is allowed then consider the types of val1, val2, and val3 in the following?

template <typename T>
struct Der: public Base
{
    void f1() {
      T val1;      // What is the type of 'val1'?
    }

    T val2;        // What is the type of 'val2'?

    typedef int T;

    T val3;        // What is the type of 'val3'?
};

The only variable to have the template parameter type T would be 'val2'.

This is because the standard requires that all members of the class be "in scope" for f1. This is why member functions can refer to member variables defined later in the class body.

The same problem can be demonstrated with typedefs too:

typedef int T;

struct S
{
  T x;
  typedef float T;
  T y;
};

Again, if this was legal then the T used for the declaration of x would refer to ::T and the T used for y would refer to typedef S::T.

This is covered by the standard under ISO 3.3.7/1:

The following rules describe the scope of names declared in classes.

...

2) A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.




回答3:


Because the second is unambigous:

You might not care or know that there was the typedev int T in the superclass, but you've just introduced T as template parameter, which makes it clear that you're referring to it when using T in Der.



来源:https://stackoverflow.com/questions/28029722/typedef-and-template-parameter-with-same-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!