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.