On Wed, 11 Mar 2020, Tam S. B. via Gcc-patches wrote: > IIUC using lambda in inline variable initializer is not ODR violation. This > is covered in CWG 2300 ( > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1510r0.html#2300 ). > > ________________________________________ > From: Libstdc++ <libstdc++-boun...@gcc.gnu.org> on behalf of Jonathan Wakely > via Libstdc++ <libstd...@gcc.gnu.org> > Sent: Wednesday, March 11, 2020 10:26 > To: Nathan Sidwell > Cc: libstd...@gcc.gnu.org; GCC Patches > Subject: Re: ODR violation in ranges > > On 11/03/20 06:08 -0400, Nathan Sidwell wrote: > >Jonathan, > >the ranges header contains code like: > > inline constexpr __adaptor::_RangeAdaptorClosure all > > = [] <viewable_range _Range> (_Range&& __r) > > { > > if constexpr (view<decay_t<_Range>>) > > return std::forward<_Range>(__r); > > else if constexpr (requires { ref_view{std::forward<_Range>(__r)}; }) > > return ref_view{std::forward<_Range>(__r)}; > > else > > return subrange{std::forward<_Range>(__r)}; > > }; > > > >(line 1236) > > > >When you strip away all the templateyness, you have: > > > > > >inline constexpr auto all = [] () {}; > > > > > >That's an ODR violation -- the initializers in different TUs are not > >the same! > > > >As you can guess, I can't turn this into a header unit (well, I can, > >but merging duplicates complains at you) > > CC libstdc++@ and Patrick. > > I did wonder if using lambdas for those global variables would be OK. > > I think we'll need a new class template for each view adaptor, rather > than using the _RangeAdaptorClosure to hold a closure. > > Patrick, can you look into that please?
IIUC, it should suffice to replace the lambda in the initializer with a function object, maybe something like: struct _All { constexpr auto operator()(...) { }; }; inline constexpr __adaptor::_RangeAdaptorClosure<_All> all; Do the lambdas in the bodies of _RangeAdaptor::operator() and _RangeAdaptorClosure::operator|() pose a problem too?