What exactly causes function to shadow type in template parameters? [duplicate]

9 hours ago 3
ARTICLE AD BOX

This is called name hiding and described in

3.3 Scope [basic.scope]

3.3.1 Declarative regions and scopes [basic.scope.declarative]

4) Given a set of declarations in a single declarative region, each of which specifies the same unqualified name,
— they shall all refer to the same entity, or all refer to functions and function templates; or
— exactly one declaration shall declare a class name or enumeration name that is not a typedef name and the other declarations shall all refer to the same variable or enumerator, or all refer to functions and function templates; in this case the class name or enumeration name is hidden (3.3.10). [...]

emphasis mine.

Note that changing the order of declaration doesn't affect the outcome:

void test(){cout<<"function"<<endl;} struct test { test(){cout<<"class"<<endl;} }; int main() { test(); return 0; }

still prints out function.

In case it isn't obvious, don't do this :)

answered Oct 13, 2014 at 14:15

Luchian Grigore's user avatar

2 Comments

You should probably point out that this is a hack, for reasons of C compatibility, and that you probably don't want to use it in actual code.

2014-10-13T14:43:50.73Z+00:00

You didn't know that it was for C compatibility, or you didn't know that it was a bad idea:-). The real reason it's there is to support the Posix function stat (which has an out parameter struct stat*); in C, you need the struct, and names after the struct are looked up in a different namespace than the others. The somewhat awkward rules in C++ are an attempt to support this, while still allowing the use of C libraries like Posix. (And I'm sure that this was documented in some early specifications, maybe the ARM.)

2014-10-13T17:12:57.873Z+00:00

From N3485 §3.3.10 [basic.scope.hiding]/2:

A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope.

Therefore, the function takes precedence over the class.

As mentioned in the comments, the class is still accessible via the class or struct keyword. If the class took precedence, the function would be unreachable.

Community's user avatar

answered Oct 13, 2014 at 14:15

Qaz's user avatar

I'm not certain either of the previous responses are the "why" for your particular instance.

Don't get me wrong; They are true and accurate.

I just think it's simpler.

In your example, you never instantiate the struct.

In other words, you declared it, but you never used it.

Since you never referenced it, it is never called.

Name precedence and such don't really apply here, since you never instantiated the struct.

Hope this helps,

-john

answered Oct 13, 2014 at 17:14

John's user avatar

2 Comments

You are supposed to cite any source or documentation to reason what you think, or provide any evidence to prove it correct. In this answer you failed to do so.

2014-10-13T18:13:51.143Z+00:00

That answer is not even logical in itself: The class is never instantiated because the precedence rules cited in the other answers require that the function is called. If the precedence rules where the other way round, a temporary object would be instantiated and the constructor would be called. So saying "precedence and such don't apply, because the struct is not instantiated" is just plain wrong.

2014-10-13T22:23:52.113Z+00:00

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Read Entire Article