Where are "temp1.cc" and "temp2.cc" so that I correct them? are they part of
the compiler?

Thanks,


pinskia at gcc dot gnu dot org wrote:
> 
> Two files are appended at the end of this report: temp1.cc and temp2.cc.
> 
> temp1.cc is the only file that causes a problem with recent releases
> of GCC.  It contains :
> 
> 1. a template definition of  Structure<S>
> 2. a template definition of  op_is_finite<S>(const Structure<S>*)
> 3. a template definition of  algebra::AlphabetSet<L> inheriting from
> Structure
> 4. a template definition of  Element<L> 
>    that calls op_is_finite(const algebra::AlphabetSet<L>*) in its ctor
> 5. a template overloaded definition for 
>                              op_is_finite<L>(const
> algebra::AlphabetSet<L>*)
> 6. a main function that instantiate Element<char>.
> 
> Because all definitions but main() are template, I expect the call to
> op_is_finite() in the ctor of Element<L> (#4) to be resolved during the 
> instantiation of Element<char> (#6) after the second definition
> of op_is_finite() (#5) has been read.  So the call would be bound
> to that second definition and not to the first.
> 
> I have tested three GCC versions :
> g++-3.4 (GCC) 3.4.6 (Debian 3.4.6-6)
> g++-4.1 (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
> g++-4.2 (GCC) 4.2.3 20071014 (prerelease) (Debian 4.2.2-3)
> 
> Both 4.1 and 4.2 behave identically: they seem to ignore the second
> definition of op_is_finite and try to call the first.
> 
> 3.4 does what we expect: it calls the second definition.
> 
> 
> We have found at least two ways to alter temp1.cc such that 4.2 will
> compile it.
> 
> - One is to move the second definition of op_is_finite() (#5) before its
>   use in the constructor of Element<L> (#4).  
> 
>   This ordering would make sense to me if the functions were not
>   template, but it's not clear why this would change anything in
>   the resolution of template overloaded functions.  I might be
>   missing something.
> 
> - Another possibility is to move AlphabetSet<L> struct out of 
>   the "algebra::" namespace.  temp2.cc contains the updated
>   code.  
> 
>   I'm really surprized that 4.2 compiles temp2.cc
>   without problem and fails on temp1.cc.
> 
> 
> 
> 
> //////////////////////////////////////////////////////
> //////////////// temp1.cc starts here ////////////////
> //////////////////////////////////////////////////////
> 
> template<typename S> struct Structure {};
> 
> template<typename S>
> bool op_is_finite (const Structure<S>*)
> {
>   // Error on purpose, this function is not expected to be instantiated.
>   return Structure<S>();
> }
> 
> namespace algebra
> {
>   template <typename L>
>   struct AlphabetSet : public Structure<AlphabetSet<L> > {};
> }
> 
> template <typename L>
> struct Element
> {
>   Element()
>   {
>     op_is_finite(static_cast<const algebra::AlphabetSet<L>*>(0));
>   }
> };
> 
> template <typename L>
> bool op_is_finite(const algebra::AlphabetSet<L>*)
> {
>   // This is the function we want to be called.
>   return true;
> }
> 
> int main()
> {
>   Element<char> alpha;
> }
> 
> // % g++-3.4 -Wall -W temp1.cc
> // % g++-4.2 -Wall -W temp1.cc
> // temp1.cc: In function 'bool op_is_finite(const Structure<S>*) [with S =
> algebra::AlphabetSet<char>]':
> // temp1.cc:21:   instantiated from 'Element<L>::Element() [with L =
> char]'
> // temp1.cc:34:   instantiated from here
> // temp1.cc:7: error: cannot convert 'Structure<algebra::AlphabetSet<char>
> >'
> to 'bool' in return
> 
> //////////////////////////////////////////////////////
> //////////////// temp2.cc starts here ////////////////
> //////////////////////////////////////////////////////
> 
> template<typename S> struct Structure {};
> 
> template<typename S>
> bool op_is_finite (const Structure<S>*)
> {
>   // Error on purpose, this function is not expected to be instantiated.
>   return Structure<S>();
> }
> 
> template <typename L>
> struct AlphabetSet : public Structure<AlphabetSet<L> > {};
> 
> template <typename L>
> struct Element
> {
>   Element()
>   {
>     op_is_finite(static_cast<const AlphabetSet<L>*>(0));
>   }
> };
> 
> template <typename L>
> bool op_is_finite(const AlphabetSet<L>*)
> {
>   // This is the function that is called, as we expected.
>   return true;
> }
> 
> int main()
> {
>   Element<char> alpha;
> }
> 
> // % g++-3.4 -Wall -W temp2.cc
> // % g++-4.2 -Wall -W temp2.cc
> 
> 
> -- 
>            Summary: overloaded template function resolves differently if
> one
>                     type is included in a namespace
>            Product: gcc
>            Version: 4.2.3
>             Status: UNCONFIRMED
>           Severity: normal
>           Priority: P3
>          Component: c++
>         AssignedTo: unassigned at gcc dot gnu dot org
>         ReportedBy: adl at gnu dot org
>  GCC build triplet: i686-pc-linux-gnu
>   GCC host triplet: i686-pc-linux-gnu
> GCC target triplet: i686-pc-linux-gnu
> 
> 
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34073
> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/-Bug-c%2B%2B-34073---New%3A-overloaded-template-function-resolves-differently-if-one-type-is-included-in-a-namespace-tf4791742.html#a13855273
Sent from the gcc - bugs mailing list archive at Nabble.com.

Reply via email to