public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Dependency loop with templates
@ 2006-11-15 14:45 Wai-chung Poon
  2006-11-15 15:31 ` Ian Lance Taylor
  0 siblings, 1 reply; 6+ messages in thread
From: Wai-chung Poon @ 2006-11-15 14:45 UTC (permalink / raw)
  To: gcc-help

I encountered compilation problems with the following
code:
 
<< A.h >>
#include <vector>
 
namespace Ser
{
    template <class T>
    size_t StreamSize(const std::vector<T> &v)
    {
        size_t Result = 0;
        for (int i = 0; i < v.size(); ++i)
               Result += StreamSize(v[i]);
        return Result;
    }
}
 
<< B.h >>
#include "cx.h"  // defines CCX
 
namespace Ser
{
    size_t StreamSize(const CCX *p); // definition in
B.cpp
}
 
<< C.cpp >>
#include "A.h"    // Line (1)
#include "B.h"    // Line (2)
 
using namespace Ser;
using namespace std;
 
int main(int argc, char *argv[])
{
    vector<CCX *> v;
    size_t Size = StreamSize(v);
}
 
------
 
The returned error is "No matching function for call
to StreamSize(CCX *const&). If I swap line (1) with
line (2) in C.cpp, or remove the namespace definition
in B.cpp, the code compiles without any problem.
Besides, the above code used to work fine with gcc
2.96 but no longer works once I upgraded the gcc to
4.1.1.
 
If I don't swap the two lines in C.cpp, is there any
other way to resolve this? Thanks.
 
Regards,
Milan.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Dependency loop with templates
  2006-11-15 14:45 Dependency loop with templates Wai-chung Poon
@ 2006-11-15 15:31 ` Ian Lance Taylor
  2006-11-15 15:51   ` Perry Smith
  0 siblings, 1 reply; 6+ messages in thread
From: Ian Lance Taylor @ 2006-11-15 15:31 UTC (permalink / raw)
  To: Wai-chung Poon; +Cc: gcc-help

Wai-chung Poon <tsdmilan@yahoo.com.hk> writes:

> I encountered compilation problems with the following
> code:
>  
> << A.h >>
> #include <vector>
>  
> namespace Ser
> {
>     template <class T>
>     size_t StreamSize(const std::vector<T> &v)
>     {
>         size_t Result = 0;
>         for (int i = 0; i < v.size(); ++i)
>                Result += StreamSize(v[i]);
>         return Result;
>     }
> }
>  
> << B.h >>
> #include "cx.h"  // defines CCX
>  
> namespace Ser
> {
>     size_t StreamSize(const CCX *p); // definition in
> B.cpp
> }
>  
> << C.cpp >>
> #include "A.h"    // Line (1)
> #include "B.h"    // Line (2)
>  
> using namespace Ser;
> using namespace std;
>  
> int main(int argc, char *argv[])
> {
>     vector<CCX *> v;
>     size_t Size = StreamSize(v);
> }
>  
> ------
>  
> The returned error is "No matching function for call
> to StreamSize(CCX *const&). If I swap line (1) with
> line (2) in C.cpp, or remove the namespace definition
> in B.cpp, the code compiles without any problem.
> Besides, the above code used to work fine with gcc
> 2.96 but no longer works once I upgraded the gcc to
> 4.1.1.
>  
> If I don't swap the two lines in C.cpp, is there any
> other way to resolve this? Thanks.


Names which are not dependent on template parameters, such as, in this
case, StreamSize, are looked up at template definition time, not at
template instantiation time.  This is known as two-phase lookup.

The simple fix here would be to have A.h include B.h.

Ian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Dependency loop with templates
  2006-11-15 15:31 ` Ian Lance Taylor
@ 2006-11-15 15:51   ` Perry Smith
  2006-11-15 15:54     ` John Love-Jensen
  2006-11-15 17:36     ` Ian Lance Taylor
  0 siblings, 2 replies; 6+ messages in thread
From: Perry Smith @ 2006-11-15 15:51 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Wai-chung Poon, gcc-help

On Nov 15, 2006, at 9:30 AM, Ian Lance Taylor wrote:

> Wai-chung Poon <tsdmilan@yahoo.com.hk> writes:
>
>> I encountered compilation problems with the following
>> code:
>>
>> << A.h >>
>> #include <vector>
>>
>> namespace Ser
>> {
>>     template <class T>
>>     size_t StreamSize(const std::vector<T> &v)
>>     {
>>         size_t Result = 0;
>>         for (int i = 0; i < v.size(); ++i)
>>                Result += StreamSize(v[i]);
>>         return Result;
>>     }
>> }
>>
>> << B.h >>
>> #include "cx.h"  // defines CCX
>>
>> namespace Ser
>> {
>>     size_t StreamSize(const CCX *p); // definition in
>> B.cpp
>> }
>>
>> << C.cpp >>
>> #include "A.h"    // Line (1)
>> #include "B.h"    // Line (2)
>>
>> using namespace Ser;
>> using namespace std;
>>
>> int main(int argc, char *argv[])
>> {
>>     vector<CCX *> v;
>>     size_t Size = StreamSize(v);
>> }
>>
>> ------
>>
>> The returned error is "No matching function for call
>> to StreamSize(CCX *const&). If I swap line (1) with
>> line (2) in C.cpp, or remove the namespace definition
>> in B.cpp, the code compiles without any problem.
>> Besides, the above code used to work fine with gcc
>> 2.96 but no longer works once I upgraded the gcc to
>> 4.1.1.
>>
>> If I don't swap the two lines in C.cpp, is there any
>> other way to resolve this? Thanks.
>
>
> Names which are not dependent on template parameters, such as, in this
> case, StreamSize, are looked up at template definition time, not at
> template instantiation time.  This is known as two-phase lookup.

Sorry to be such a pest about this.  I still don't understand this  
two phase lookup.  Here is my logic:

StreamSize(v[i]) depends upon v[i] which depends upon std::vector<V>  
which depends upon V.  So, StreamSize does (according to my logic)  
depend upon the template argument.  Where did I go wrong?

Perry Smith
Ease Software, Inc.
pedz@easesoftware.com
http://www.easesoftware.com

Low cost SATA Products for IBMs p5, pSeries, and RS/6000 AIX systems



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Dependency loop with templates
  2006-11-15 15:51   ` Perry Smith
@ 2006-11-15 15:54     ` John Love-Jensen
  2006-11-15 17:36     ` Ian Lance Taylor
  1 sibling, 0 replies; 6+ messages in thread
From: John Love-Jensen @ 2006-11-15 15:54 UTC (permalink / raw)
  To: Perry Smith; +Cc: MSX to GCC

Hi Perry,

From http://www.research.att.com/~bs/glossary.html

two-phase lookup - a somewhat complicated mechanism used in compilation of
templates. Names that do not depend on a template parameter are looked up
(and bound) early, i.e., when the template template definition is first seen
("phase 1 lookup"). Names that depend on a template parameter are looked up
late, i.e. during template instantiation ("phase 2 lookup") so that the
lookup can find names relating to actual template arguments. TC++PL C::13.8.

HTH,
--Eljay

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Dependency loop with templates
  2006-11-15 15:51   ` Perry Smith
  2006-11-15 15:54     ` John Love-Jensen
@ 2006-11-15 17:36     ` Ian Lance Taylor
  2006-11-15 17:50       ` Ian Lance Taylor
  1 sibling, 1 reply; 6+ messages in thread
From: Ian Lance Taylor @ 2006-11-15 17:36 UTC (permalink / raw)
  To: Perry Smith; +Cc: Wai-chung Poon, gcc-help

Perry Smith <pedz@easesoftware.com> writes:

> Sorry to be such a pest about this.  I still don't understand this
> two phase lookup.  Here is my logic:
> 
> StreamSize(v[i]) depends upon v[i] which depends upon std::vector<V>
> which depends upon V.  So, StreamSize does (according to my logic)
> depend upon the template argument.  Where did I go wrong?

In fact, I think you're right, and I'm wrong.  Sorry about that.

I think this may be a bug in the compiler.  Here is a reduced test
case:

class c;
template<typename T> class tm { public: const T& g() const; };
namespace n {
  template <class T> int fn(const tm<T> &v) { return fn(v.g());  }
  int fn(const c *p);
}
int main() { tm<c *> v; return n::fn(v); }

Interestingly, it works as expected without the namespace.

I'll file this as a bug report and see what happens.

Thanks for pushing on this.

Ian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Dependency loop with templates
  2006-11-15 17:36     ` Ian Lance Taylor
@ 2006-11-15 17:50       ` Ian Lance Taylor
  0 siblings, 0 replies; 6+ messages in thread
From: Ian Lance Taylor @ 2006-11-15 17:50 UTC (permalink / raw)
  To: Perry Smith; +Cc: Wai-chung Poon, gcc-help

Ian Lance Taylor <iant@google.com> writes:

> I think this may be a bug in the compiler.  Here is a reduced test
> case:
> 
> class c;
> template<typename T> class tm { public: const T& g() const; };
> namespace n {
>   template <class T> int fn(const tm<T> &v) { return fn(v.g());  }
>   int fn(const c *p);
> }
> int main() { tm<c *> v; return n::fn(v); }
> 
> Interestingly, it works as expected without the namespace.
> 
> I'll file this as a bug report and see what happens.

Filed as http://gcc.gnu.org/PR29844.

Ian

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2006-11-15 17:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-11-15 14:45 Dependency loop with templates Wai-chung Poon
2006-11-15 15:31 ` Ian Lance Taylor
2006-11-15 15:51   ` Perry Smith
2006-11-15 15:54     ` John Love-Jensen
2006-11-15 17:36     ` Ian Lance Taylor
2006-11-15 17:50       ` Ian Lance Taylor

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).