Pythy (http://pfultz2.github.com/Pythy/) does something akin to: template <typename T> typename std::remove_reference<T>::type *addr(T &&t) { return &t; } template <class T0, class T1> struct min_t { constexpr static auto *f = false ? addr([](T0 x, T1 y){ return x < y ? x : y; }) : nullptr; }; Which gcc (4.7.2 and 4.8.0 git master) cannot evaluate. clang and visual studio 2012 work fine. I know this is not strictly needed by gcc 4.8 since it has deduced auto without the late specifier (which the other compilers lack), but its highly convenient to have pythy work on all c++11 compilers.
I really think that Pythy should fix this implementation, because it is not supported by the C++11 standard. Any compiler accepting that is defect. According to 9.4.2 p3: "A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression." As of 5.19 p2 the appearance of a lambda-expression prevents an expression from satisfying the requirements of a (core) constant expression. But changing your example to template <typename T> T* addr(T& t) { return &t; } bool less(int x, int y) { return x < y ? x : y; } const static auto* f = addr(less); indeed points to a defect of gcc, not being able to deduce auto here. I think this is the same bug that I can remember (but cannot find at the very moment) which shows a similar problem during overload resolution in templates when involving function addresses such as in template <typename T> T* addr(T& t) { return &t; } bool less(int x, int y) { return x < y ? x : y; } template<typename T> int deduce(const T*) { return 0; } int i = deduce(addr(less)); This example should be accepted, but gcc doesn't like it saying: "error: no matching function for call to 'deduce(bool (*)(int, int))'| note: candidate is:| note: template<class T> int deduce(const T*)| note: template argument deduction/substitution failed:| note: types 'const T' and 'bool(int, int)' have incompatible cv-qualifiers"
Daniel, you mean PR54111 maybe?
(In reply to comment #2) Hmmh, it doesn't look like that one, maybe I was wrong about an existing issue. But it seems that gcc doesn't ignore the const (in "const T*" or "const auto*") for functions here, which seems to be the root of the second problem (This is *not* attempting to form a function with cv-qualifier-seq). Both template <typename T> T* addr(T& t) { return &t; } bool less(int x, int y) { return x < y ? x : y; } static auto* f = addr(less); and template <typename T> T* addr(T& t) { return &t; } bool less(int x, int y) { return x < y ? x : y; } template<typename T> int deduce(T*) { return 0; } int i = deduce(addr(less)); are accepted as they should.
(In reply to comment #3) > But it seems that gcc doesn't ignore the const (in "const T*" or "const auto*") > for functions here, which seems to be the root of the second problem (This is > *not* attempting to form a function with cv-qualifier-seq). I withdraw my interpretation that it is *clear* here that during template argument deduction we can successfully match a "const T" with a function type. This looks like a core language problem to me and I'll notify CWG in regard to this.
I need to insert another correction. My attempt to simplify the reporters bug failed because I was mislead by the report description that "visual studio 2012 work fine" interpreting this to mean the Microsoft Visual Studio 2012 compiler. But that one does not understand 'constexpr' therefore my reduction to 'const' was not equivalent. (In reply to comment #1) > I really think that Pythy should fix this implementation, because it is not > supported by the C++11 standard. Any compiler accepting that is defect. This statement still holds. The original code is not conforming. The following presents a conforming code that reproduces the problem: template <class T0, class T1> struct min_t { static bool less(T0 x, T1 y) { return x < y ? x : y; } constexpr static auto* f = &less; // #5 }; min_t<int, int> mi; // #8 "8| required from here| 5|error: declaration of 'constexpr auto* const min_t<int, int>::f' has no initializer" Please ignore the part about const T in template deduction. This is a different issue and not related to this one.
Thus, Daniel, is this invalid?
(In reply to comment #6) > Thus, Daniel, is this invalid? I think this part of the problem is indeed valid: template <class T0, class T1> struct min_t { static bool less(T0 x, T1 y) { return x < y ? x : y; } constexpr static auto* f = &less; // #5 }; min_t<int, int> mi; // #8 "8| required from here| 5|error: declaration of 'constexpr auto* const min_t<int, int>::f' has no initializer" (With or without & in front of less) According to my understanding this should be accepted.
Ah, Ok, I was a bit lost ;) Thanks. However, my (very rough) feeling is that we have got already quite a bit in Bugzilla in the area, constexpr, auto, pointers...
Uhm, for testcase in Comment #7 we call finish_static_data_member_decl from instantiate_class_template_1 and we explicitly pass init == NULL_TREE, no chances for things to work from this point on. Interestingly this is the *only* place in pt.c where we call finish_static_data_member_decl.
Oh, Comment #7 is really the same as PR55003. *** This bug has been marked as a duplicate of bug 55003 ***