C++ Logo

SG10

Advanced search

Subject: Re: [SG10] P0304: constexpr addressof
From: Richard Smith (richard_at_[hidden])
Date: 2016-03-13 23:08:04


On Sun, Mar 13, 2016 at 8:47 PM, Richard Smith <richard_at_[hidden]> wrote:
> On Sun, Mar 13, 2016 at 6:29 PM, Agustín Bergé <agustinberge_at_[hidden]> wrote:
>> On 3/13/2016 10:16 PM, Richard Smith wrote:
>>>
>>> On Fri, Mar 11, 2016 at 11:30 AM, Daniel Krügler
>>> <daniel.kruegler_at_[hidden]> wrote:
>>>>
>>>> 2016-03-11 20:27 GMT+01:00 Agustín Bergé <agustinberge_at_[hidden]>:
>>>>>
>>>>> On 3/11/2016 4:14 PM, Nelson, Clark wrote:
>>>>>>
>>>>>> Agustin raised the question of whether there should be a macro to
>>>>>> indicate the presence of the fix for LWG2296. I made a couple of
>>>>>> replies suggesting that, to me, the answer is not obviously "yes".
>>>>>>
>>>>>> So far, no one (not even Agustin) has made any further comment.
>>>>>
>>>>>
>>>>> I said that if there's no macro I'd prefer to leave the code broken.
>>>>> That should have implied my motivation is weak. I think a macro fits the
>>>>> bill, but if lacks in popularity I'm not going to push for it.
>>>>
>>>>
>>>> I tentatively agree, I see no need for a feature macro here.
>>>
>>>
>>> I can imagine a macro being useful:
>>>
>>> struct optional {
>>> bool b;
>>> T t;
>>> constexpr T *get() {
>>> return b ?
>>> #if __cpp_constexpr_addressof
>>> std::addressof(t)
>>> #else
>>> &t
>>> #endif
>>> : nullptr;
>>> }
>>> };
>>
>>
>> That's my use case :)
>>
>>> The idea here is that it's more important that get() is constexpr than
>>> that it works if there's an overloaded operator&, so addressof is only
>>> used if it would actually work in a constant expression. Achieving
>>> this result with SFINAE seems difficult.
>>
>>
>> This appears to do the trick, but there's a chance that it is ill-formed:
>>
>> #if 0
>> using std::addressof;
>> #else
>> template <typename T>
>> constexpr T* addressof(T& v) { return &v; }
>> #endif
>>
>> struct is_addressof_constexpr {
>> static int _probe;
>>
>> template <typename T, T* = addressof(_probe)>
>
> If you use "std::addressof" instead of "addressof", I think this
> default template argument has no valid instantiations in C++14, so is
> ill-formed (no diagnostic required). If you don't qualify it, it can
> find the wrong addressof via ADL.

Hmm, here's a trick:

  bool addressof_is_constexpr =
noexcept(addressof(addressof_is_constexpr) ? 0 : throw);

... but it doesn't work on Clang (it's always false regardless of
whether addressof is constexpr) and it ICEs ICC.

>> static std::true_type check(T);
>>
>> static std::false_type check(...);
>>
>> static constexpr bool value =
>> decltype(check(0))::value;
>> };
>>
>> static_assert(is_addressof_constexpr::value, "");
>>
>>
>> Regards,
>> --
>> Agustín K-ballo Bergé
>> http://talesofcpp.fusionfenix.com


SG10 list run by herb.sutter at gmail.com