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.