Am 19.02.20 um 13:43 schrieb Jonathan Wakely: > On Wed, 19 Feb 2020 at 11:17, Marc Glisse wrote: >> >> On Wed, 19 Feb 2020, Klaus Doldinger wrote: >> >>> Am 19.02.20 um 11:02 schrieb Jonathan Wakely: >>>> On Wed, 19 Feb 2020 at 07:53, Klaus Doldinger >>>> <klaus.doldinger64@xxxxxxxxx> wrote: >>>>> >>>>> The following was possible in v9: >>>>> >>>>> template<auto N> >>>>> struct A { >>>>> constexpr auto size() const { >>>>> return N; >>>>> } >>>>> }; >>>>> >>>>> template<typename A> >>>>> void foo(const A& a) { >>>>> constexpr auto s = a.size(); >>>>> } >>>>> >>>>> int main() { >>>>> A<10> x1; >>>>> foo(x1); >>>>> } >>>>> >>>>> In v10 this is rejected. >>>>> >>>>> Looks like a bug? >> >> Clang also rejects it. >> >>>> No, I don't think so. The parameter a is not a constant expression, so >>>> a.size() is not a constant expression, so can't be used to initialize >>>> a constexpr variable. >> >> Why not make size() static? >> >>> That would be weird. >>> If so, the follwing would be impossible: >>> >>> std::array<int, 10> a; >>> std::array<int, a.size()> b; >> >> You can still use decltype and tuple_size to access that information. > > And it works if 'a' is usable in a constant expression, e.g. because > it has static storage duration. > > It doesn't work if it's an automatic variable, or if you pass it by > reference to a non-constexpr function, which is the problem in the > OP's original example. Well, the following works: A<10> x1; A<x1.size()> x2; std::array<int, 10> a; std::array<int, a.size()> b; Here x1 is not a constant expression, and it is accepted. Why? Please explain what the difference is to what in function foo() happens. If function foo() is changed to template<typename T> void foo(T a) { constexpr auto s = a.size(); } it is also expected. Thats not consistent I would say.