Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"template" keyword not needed? [gcc/clang/Comeau bug?]

Tags:

c++

templates

g++

Here is the test code

template <class T> void f()
{
  T t;
  t.f<T>(0); //compiles even without the "template" keyword, what am I missing?
}

class abc
{
  public:
  template <typename T>
  void f (int){}
};

int main()
{
  f<abc>();
}

I am using g++ 4.4.6. Thanks

P.S: I have edited my question considerably. Please don't mind.

EDIT : I asked this question to EDG people and this is what Mike Herrick had to say

We do diagnose this as an error in --strict mode as well as any mode that enables dependent name lookup (e.g., --dep_name, --parse_templates). Dependent name lookup is disabled in GNU emulation modes, so we don't emit this error in that case.

Dependent name processing requires that nonclass prototype instantiations be enabled (see below). As with nonclass prototype instantiations, enabling dependent name lookup is likely to cause compilation errors when compiling code that was not written with the feature in mind.

The dependent name lookup rules require that nondependent names be looked up at the point of use in the template definition, and that overload resolution be performed on nondependent calls at that point. For dependent calls, the set of names considered is the set visible at the point of use in the template definition plus any names made visible by argument-dependent lookup at the point of instantiation. Note that built-in types have no associated namespaces, so calls with only built-in types can only resolve to names visible in the template definition. Furthermore, names from dependent base classes are not visible to unqualified lookups.

The following illustrates some of the most common code problems encountered when using dependent name lookup:

template <class T> struct B {
    void f();
  };

template <class T> struct A : public B<T> {
    X x;  // error: X not visible yet (formerly an error in strict mode)
    void g() {
      f();        // error: B<T>::f not visible
      this->f();  // must be written this way
      h(1);  // error: h(int) not visible using argument-dependent lookup
    }
  };
struct X {};
void h(int);
A<int> ai;
like image 294
Prasoon Saurav Avatar asked Jan 24 '12 12:01

Prasoon Saurav


2 Answers

The template keyword is required both because t is a dependent name and because f<T> is a dependent member function template specialization. The relevant specification is scattered throughout clause 14, but starts at §14.2/4 (in both C++03 and C++11).

The problem is due to incorrect name lookup: gcc is finding the namespace-scope function template f at the point of declaration, then at the point of instantiation resolves f to the member function template of abc.

If you rename either the namespace-scope function template or the member function template, you will get the correct behavior from the compiler.

This is a longstanding gcc bug:

Code with missing "template" keyword wrongly accepted

Weird clash with same names in different scopes

See also the many duplicate bugs resolved against both of those. I don't see a Clang bug open for this.

Name lookup from within a function template was underspecified in C++03; there were many defects reported on the subject and the specification has undergone major changes in C++11 to clarify details and corner cases and to fix subtle problems.

like image 125
James McNellis Avatar answered Nov 15 '22 19:11

James McNellis


I could be wrong, but I think this is a bug in GCC. Consider the following case:

template <class T> bool f() {T t = {2}; return t.f < 4;}

struct abc { int f; };

int main() { f<abc>(); }

I would expect that to compile just fine, but GCC (and Clang) assume that t.f names a template function, and expect a closing >. The relevant part of the standard is §14.2/4.

That said, I am a bit hesitant to claim that a bug like this could exist in both Clang and GCC without some more evidence. I will get back after some more standard diving.

like image 38
Mankarse Avatar answered Nov 15 '22 19:11

Mankarse