[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 --- Comment #8 from Fernando Pelliccioni fpelliccioni at gmail dot com 2012-05-07 13:24:02 UTC --- Sorry, the comments were wrong. Here the corrected code with proper comments. Tested with GCC 4.7.1 and GCC 4.6.3 // g++ -std=c++0x gcc_error_simple.cpp // g++ -DWITH_USING_DECLARATION -std=c++0x gcc_error_simple.cpp #include type_traits template typename T struct Base { template typename T2 typename std::enable_ifstd::is_sameT, T2::value, T::type get() { return T2(); } }; template typename T struct Derived : Baseint { typedef Baseint base; #ifdef WITH_USING_DECLARATION using base::get; #endif template typename T2 typename std::enable_ifstd::is_sameT, T2::value, T::type get() { return T2(); } }; int main( /* int argc, char* argv[] */ ) { Deriveddouble d; auto xxx = d.getdouble(); auto yyy = d.getint();// #ifndef WITH_USING_DECLARATION - Compile-time error- GCC is behaving Correctly!!! Baseint::getint() is hidden! // #ifdef WITH_USING_DECLARATION - No Compile-time error - GCC is behaving incorrectly. Baseint::getint() must be hidden. return 0; }
[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 --- Comment #9 from Daniel Krügler daniel.kruegler at googlemail dot com 2012-05-07 13:50:10 UTC --- (In reply to comment #8) [..] Here the corrected code with proper comments. [..] auto yyy = d.getint();// #ifndef WITH_USING_DECLARATION - Compile-time error- GCC is behaving Correctly!!! Baseint::getint() is hidden! // #ifdef WITH_USING_DECLARATION - No Compile-time error - GCC is behaving incorrectly. Baseint::getint() must be hidden. Its a mystery to me why get() should return an T2 when the return type is T, but anyway: I cannot confirm your results for gcc 4.8.0 20120429 (experimental). Here the second case is correctly rejected.
[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 --- Comment #10 from Fernando Pelliccioni fpelliccioni at gmail dot com 2012-05-07 13:58:38 UTC --- (In reply to comment #9) (In reply to comment #8) [..] Here the corrected code with proper comments. [..] auto yyy = d.getint();// #ifndef WITH_USING_DECLARATION - Compile-time error- GCC is behaving Correctly!!! Baseint::getint() is hidden! // #ifdef WITH_USING_DECLARATION - No Compile-time error - GCC is behaving incorrectly. Baseint::getint() must be hidden. Its a mystery to me why get() should return an T2 when the return type is T, but anyway: I cannot confirm your results for gcc 4.8.0 20120429 (experimental). Here the second case is correctly rejected. T and T2 are the same type. It is the same, could be... return T(); I'm glad that is resolved in 4.8.0 I can't test it, I don't have that version. Thanks!
[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 --- Comment #7 from Daniel Krügler daniel.kruegler at googlemail dot com 2012-05-06 17:34:10 UTC --- (In reply to comment #5) Here is a simplified code - gcc_error_simple.cpp Shows two facets of the error. See the comments in the attached file. Fixed and simplified that code we have: //--- templatetypename, typename, typename struct enable_same {}; templatetypename T, typename U struct enable_sameT, T, U { typedef U type; }; template typename T struct Base { T u; template typename T2 typename enable_sameT, T2, T::type get() { return u; } }; template typename T struct Derived : Baseint { typedef Baseint base; #ifdef WITH_USING_DECLARATION using base::get; #endif template typename T2 typename enable_sameT, T2, T::type get() { return this-u;} // Line 32 }; int main() { Deriveddouble d; d.getdouble(); d.getint(); // Line 39 } //--- Using gcc 4.8.0 20120429 (experimental) I see different results (I see the same thing with your unchanged code taking into account that a function returning no-void is expected to be rejected): a) #ifndef WITH_USING_DECLARATION: The code is accepted as it should. b) #ifdef WITH_USING_DECLARATION: The code is rejected as it should: In function 'int main()':| 39|error: no matching function for call to 'Deriveddouble::get()'| 39|note: candidate is:| 32|note: templateclass T2 typename enable_sameT, T2, T::type Derived::get() [with T2 = T2; T = double]| |32|note: template argument deduction/substitution failed:| 39| required from here| 32|error: no type named 'type' in 'struct enable_samedouble, int, double'| Even though the third line of the diagnostics is a bit misleading it is certainly correct the function call, because the base class get template is hidden without the using-declaration. Summarizing, it seems that the variadic code is broken, not the non-variadic case.
[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 Daniel Krügler daniel.kruegler at googlemail dot com changed: What|Removed |Added CC||daniel.kruegler at ||googlemail dot com --- Comment #1 from Daniel Krügler daniel.kruegler at googlemail dot com 2012-05-05 16:32:18 UTC --- I agree that the code needs to be rejected, but I think the invalid expression should be ov.getdouble() instead of ov.getint() as indicated by the code comment. The same defect also exists in 4.8.0 HEAD.
[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 fabien at gcc dot gnu.org changed: What|Removed |Added CC||fabien at gcc dot gnu.org --- Comment #2 from fabien at gcc dot gnu.org 2012-05-05 18:04:26 UTC --- The testcase does not seem to be reduced at the minimum. Would you mind reducing it?
[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 --- Comment #3 from Daniel Krügler daniel.kruegler at googlemail dot com 2012-05-05 18:57:03 UTC --- Reduced test-case: //- templatetypename, typename, typename struct enable_same {}; templatetypename T, typename U struct enable_sameT, T, U { typedef U type; }; template typename ...Ts struct other_variant { void get(){} }; template typename T, typename ...Ts struct other_variantT, Ts... : other_variantTs... { T u; using other_variantTs...::get; template typename T2 typename enable_sameT, T2, T::type get(){ return u; } }; int main() { other_variantint, double ov; ov.getdouble(); } //- It should be added, that it is important that other_variant has a second template argument of double here (e.g. 'bool' won't work): It seems as if within the member template get of the partial specialization T behaves as if it were type double within this member declaration. The hypotheses becomes some evidence, if we change the implementation of the get template as follows: template typename T2 typename enable_sameT, T2, T::type get(){ typename enable_sameT, double, bool::type dummy; return u; } This also is accepted, even though T is of type int. The curiosity increases about the interpretation of the deduced type of 'T' within the partial specialization, if we add seemingly contradictory typedefs to the class body of the specialization as follows: //--- templatetypename, typename, typename struct enable_same {}; templatetypename T, typename U struct enable_sameT, T, U { typedef U type; }; template typename ...Ts struct other_variant { void get(){} }; template typename T, typename ...Ts struct other_variantT, Ts... : other_variantTs... // Line 18 { T u; typename enable_sameT, int, wchar_t::type dummy1; // L. 22: Should be OK typename enable_sameT, double, char::type dummy2; // Should be an error using other_variantTs...::get; template typename T2 typename enable_sameT, T2, T::type get(){ typename enable_sameT, double, bool::type dummy; // Should be an error return u; } }; int main() { other_variantint, double ov; // Line 37 ov.getdouble(); } //--- On gcc 4.8.0 20120429 (experimental) I get the following diagnostics: 18| required from 'struct other_variantint, double'| 37| required from here| 22|error: no type named 'type' in 'struct enable_samedouble, int, wchar_t'| 37| required from here| 23|error: no type named 'type' in 'struct enable_sameint, double, char'| 38| required from here| 30|warning: unused variable 'dummy' [-Wunused-variable]| Note that lines 22 and 23 describe the affected instantiations as enable_samedouble, int, wchar_t and enable_sameint, double, char thus T seems to be once double and once int within the same instantiation - quite amusing ;-)
[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 --- Comment #4 from Fernando Pelliccioni fpelliccioni at gmail dot com 2012-05-05 21:58:53 UTC --- Created attachment 27321 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=27321 simplified source code version
[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 --- Comment #5 from Fernando Pelliccioni fpelliccioni at gmail dot com 2012-05-05 22:00:05 UTC --- Here is a simplified code - gcc_error_simple.cpp Shows two facets of the error. See the comments in the attached file.
[Bug c++/53236] using declaration and base function template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236 --- Comment #6 from Fernando Pelliccioni fpelliccioni at gmail dot com 2012-05-05 22:01:23 UTC --- // g++ -std=c++11 gcc_error_simple.cpp // g++ -DWITH_USING_DECLARATION -std=c++11 gcc_error_simple.cpp #include iostream #include type_traits #include typeinfo template typename T struct Base { template typename T2 typename std::enable_ifstd::is_sameT, T2::value, T::type get() { } }; template typename T struct Derived : Baseint { typedef Baseint base; #ifdef WITH_USING_DECLARATION using base::get; #endif template typename T2 typename std::enable_ifstd::is_sameT, T2::value, T::type get() { } }; int main( /* int argc, char* argv[] */ ) { Deriveddouble d; auto xxx = d.getdouble(); //std::cout typeid(xxx).name() std::endl; auto yyy = d.getint();// #ifndef WITH_USING_DECLARATION - Compile-time error- GCC is behaving incorrectly. Baseint::getint() should not be hidden // #ifdef WITH_USING_DECLARATION - No Compile-time error - GCC is behaving incorrectly. Baseint::getint() must be hidden. //std::cout typeid(yyy).name() std::endl; return 0; }