public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Recursive template inline functions (C++)
@ 2008-05-21 22:05 Ling Li
  0 siblings, 0 replies; only message in thread
From: Ling Li @ 2008-05-21 22:05 UTC (permalink / raw)
  To: gcc

[-- Attachment #1: Type: text/plain, Size: 3268 bytes --]

Somehow g++ 3.4.3 can compile all the attached C++ programs, but g++ 4.2.4 
can only compile the first one. I probably abused the template inline 
functions in a bad way, but anyway could someone help to explain what I did 
wrong?

===== Case 1 =====
template <class T>
inline T f (T i) {
     T j = i - 1;
     return g(&j) + i;
}

template <class T>
inline T g (T* i) {
     if (*i == 0) return 0;
     return f(*i);
}
=====

Both g++ 3.4.3 and 4.2.4 know where to find g() while instantiate f().


===== Case 2 (change the name of g() to f()) =====
template <class T>
inline T f (T i) {
     T j = i - 1;
     return f(&j) + i;
}

template <class T>
inline T f (T* i) {
     if (*i == 0) return 0;
     return f(*i);
}
=====

g++ 4.2.4 doesn't seem to know about the 2nd template function of f(), and 
keeps coerce int* into int:

fwd-template-inline2.cpp: In function T f(T) [with T = int]:
fwd-template-inline2.cpp:14:   instantiated from here
fwd-template-inline2.cpp:4: error: invalid conversion from int* to int
fwd-template-inline2.cpp: In function T f(T) [with T = int*]:
fwd-template-inline2.cpp:4:   instantiated from T f(T) [with T = int]
fwd-template-inline2.cpp:14:   instantiated from here
fwd-template-inline2.cpp:4: error: invalid operands of types int** and int* 
to binary operator+
fwd-template-inline2.cpp: In function T f(T) [with T = int**]:
fwd-template-inline2.cpp:4:   instantiated from T f(T) [with T = int*]
fwd-template-inline2.cpp:4:   instantiated from T f(T) [with T = int]
fwd-template-inline2.cpp:14:   instantiated from here
fwd-template-inline2.cpp:4: error: invalid operands of types int*** and 
int** to binary operator+
fwd-template-inline2.cpp: In function T f(T) [with T = int***]:
fwd-template-inline2.cpp:4:   instantiated from T f(T) [with T = int**]
fwd-template-inline2.cpp:4:   instantiated from T f(T) [with T = int*]
fwd-template-inline2.cpp:4:   instantiated from T f(T) [with T = int]
fwd-template-inline2.cpp:14:   instantiated from here
...


===== Case 3 ====
#include <vector>

template <class T>
inline size_t f (const T* x) {
     if (x) return f(*x);
     return 0;
}

template <class T>
inline size_t f (const std::vector<T>& x) {
     return x.size();
}
=====

Similar to case 2, g++ 4.2.4 doesn't see the 2nd definition, and complains 
about no matching function.

fwd-template-inline3.cpp: In function size_t f(const T*) [with T = 
std::vector<double, std::allocator<double> >]:
fwd-template-inline3.cpp:16:   instantiated from here
fwd-template-inline3.cpp:5: error: no matching function for call to f(const 
std::vector<double, std::allocator<double> >&)


I understand that adding a forward declaration of the 2nd definition, like 
the line below, would solve the problem of Case 3 (and Case 2 as well).

template <class T>
inline size_t f (const std::vector<T>&);

However, I am not sure if the compiler would still honor the "inline" hint. 
Actually, I don't even know if including "inline" in the forward 
declaration make any sense, since forward declaration means the definition 
is not available at this moment.

And anyway, g++ 3.4.3 is quite happy with all cases, so it is confusing 
which g++ version actually does the correct thing.

Any opinions would be highly appreciated! Thanks!

--Ling

[-- Attachment #2: fwd-template-inline1.cpp --]
[-- Type: text/plain, Size: 200 bytes --]

template <class T>
inline T f (T i) {
    T j = i - 1;
    return g(&j) + i;
}

template <class T>
inline T g (T* i) {
    if (*i == 0) return 0;
    return f(*i);
}

int main () {
    return f(3);
}

[-- Attachment #3: fwd-template-inline2.cpp --]
[-- Type: text/plain, Size: 200 bytes --]

template <class T>
inline T f (T i) {
    T j = i - 1;
    return f(&j) + i;
}

template <class T>
inline T f (T* i) {
    if (*i == 0) return 0;
    return f(*i);
}

int main () {
    return f(3);
}

[-- Attachment #4: fwd-template-inline3.cpp --]
[-- Type: text/plain, Size: 265 bytes --]

#include <vector>

template <class T>
inline size_t f (const T* x) {
    if (x) return f(*x);
    return 0;
}

template <class T>
inline size_t f (const std::vector<T>& x) {
    return x.size();
}

int main () {
    std::vector<double> vd(10);
    return f(&vd);
}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-05-21 22:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-21 22:05 Recursive template inline functions (C++) Ling Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).