Templatized function call interpreted as 'operator<' on gcc


K

kcsasquatch

All,

I have the following C++ code that does not compile under gcc 4.2.1 or
4.4.3. It *does* compile on http://comeaucomputing.com/tryitout/
version 4.3.10.1 Beta2.

Is this valid C++ code (as it seems), or is there a real syntax error
that Comeau is not catching?

template<typename T>
class A
{
public:

template<int Flags>
void foo(T *text)
{
return;
}
};

template<typename T>
class B : public A<T>
{
public:
typedef A<const char> base;

template<int Flags>
void foo(T *text)
{
A<T>::foo<Flags>(text); // ERROR
static_cast<A<T>*>(this)->foo<Flags>(text); // OK
base::foo<Flags>(text); // OK
}
};

int main()
{
B<const char> b;
b.foo<1>("bar");
return 0;
}


% g++ main.cpp
main.cpp: In member function ‘void B<T>::foo(T*) [with int Flags = 1,
T = const char]’:
main.cpp:32: instantiated from here
main.cpp:23: error: invalid operands of types ‘<unresolved overloaded
function type>’ and ‘int’ to binary ‘operator<’



If it's an error, the gcc error message could be improved :)


Tested on following compilers:
$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3

Thanks in advance,
Kevin Campbell
 
Ad

Advertisements

G

Gil

All,

I have the following C++ code that does not compile under gcc 4.2.1 or
4.4.3.  It *does* compile onhttp://comeaucomputing.com/tryitout/
version 4.3.10.1 Beta2.

Is this valid C++ code (as it seems), or is there a real syntax error
that Comeau is not catching?

template<typename T>
class A
{
    public:

    template<int Flags>
    void foo(T *text)
    {
        return;
    }

};

template<typename T>
class B : public A<T>
{
public:
    typedef A<const char> base;

    template<int Flags>
    void foo(T *text)
    {
        A<T>::foo<Flags>(text);                         // ERROR
        static_cast<A<T>*>(this)->foo<Flags>(text);     // OK
        base::foo<Flags>(text);                         // OK
    }

};

int main()
{
        B<const char> b;
        b.foo<1>("bar");
        return 0;

}

% g++ main.cpp
main.cpp: In member function ‘void B<T>::foo(T*) [with int Flags = 1,
T = const char]’:
main.cpp:32:   instantiated from here
main.cpp:23: error: invalid operands of types ‘<unresolved overloaded
function type>’ and ‘int’ to binary ‘operator<’

If it's an error, the gcc error message could be improved :)

Tested on following compilers:
$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3

Thanks in advance,
Kevin Campbell

if some name of a member template (specialization) appears after ., -
, or :: operators and the name has qualified template parameters
(explicit), use keyword template:

A<T>::template foo<Flags>(text);

w/o template keyword compiler might interpret the < as a less-than
operator.
 
Ad

Advertisements

J

Johannes Schaub (litb)

kcsasquatch said:
All,

I have the following C++ code that does not compile under gcc 4.2.1 or
4.4.3. It *does* compile on http://comeaucomputing.com/tryitout/
version 4.3.10.1 Beta2.

Is this valid C++ code (as it seems), or is there a real syntax error
that Comeau is not catching?

template<typename T>
class A
{
public:

template<int Flags>
void foo(T *text)
{
return;
}
};

template<typename T>
class B : public A<T>
{
public:
typedef A<const char> base;

template<int Flags>
void foo(T *text)
{
A<T>::foo<Flags>(text); // ERROR
static_cast<A<T>*>(this)->foo<Flags>(text); // OK
base::foo<Flags>(text); // OK
}
};

int main()
{
B<const char> b;
b.foo<1>("bar");
return 0;
}


% g++ main.cpp
main.cpp: In member function ‘void B<T>::foo(T*) [with int Flags = 1,
T = const char]’:
main.cpp:32: instantiated from here
main.cpp:23: error: invalid operands of types ‘<unresolved overloaded
function type>’ and ‘int’ to binary ‘operator<’

Only the third one is valid. The second and first one need "->template" and
"::template" respectively. Comeau is not conforming. Note that you can
construct cases that are valid with and without "::template" and produce
different results for each

#include <iostream>

struct A {
template<typename T>
static A f(T) {
return A();
}

template<typename T> operator T() { return T(); }
};

template<typename U>
int g() {
U u;
typedef A (*funcPtrType)(int());
return !(funcPtrType)u.f < int() > (0);
}

int main() {
std::cout << g<A>() << std::endl;
}

Now, that prints 0. But if you insert "template" before "f<int()>" it's
going to putput 1.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top