Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[meta.logical] unclear wording #2548

Open
FrankHB opened this issue Dec 3, 2018 · 7 comments
Open

[meta.logical] unclear wording #2548

FrankHB opened this issue Dec 3, 2018 · 7 comments
Assignees

Comments

@FrankHB
Copy link
Contributor

FrankHB commented Dec 3, 2018

In N4778 [meta.logical]/2

then instantiating conjunction<B1, ..., BN>::value does not require the instantiation of Bj::value for j > i

What is "the instantiation of Bj::value"?

(The font of j should also be fixed.)

The change in #1133 (LWG 2567) also introduces another (possibly non-editorial) problem: does the explicit cast to bool of value mandated? For example:

#include <type_traits>

struct B
{
  constexpr explicit operator bool() const noexcept {return true;}
};

struct C
{
  static constexpr const B value = B();
};

int main()
{
  static_assert(bool(std::conjunction<C, std::true_type>::value));
}

Is the program above well-formed?

It seems intentionally ill-formed as per "shall have a member value which is convertible to bool" wording in [meta.logical]/4. (Is this presumely "implicit", or like std::is_convertible?) Then bool(Bj::value) is not appropriate as it suggests the cast shall be supported, as implemented in cppreference.

Otherwise, libstdc++, libc++ and MSVC currently all has the bug concerned with the resolution of LWG 2567, and [meta.logical]/4 should be reworded to clarify the intention. I guess this is not intentional because a) it was not proposed, which should be consisted to existed implementations; b) the context here is more like operands of && but not if, which needs no contextually conversion, so omission of explicit cast should not be encouraged; and c) it is an editorial side effect implied by the title of #1133: "fixed in add further explicit boolean conversions editorially".

@jwakely
Copy link
Member

jwakely commented Dec 3, 2018

What is "the instantiation of Bj::value"?

It seems clear to me.

Maybe it would be more precise to say "does not require the definition of the static data member Bj::value to exist" with a cross-reference to [temp.inst]. (Done in #2550)

@jwakely
Copy link
Member

jwakely commented Dec 3, 2018

(The font of j should also be fixed.)

I'm not sure what you mean by "fixed" but I've submitted #2549 to use math mode for the subscripts i, j, 1 and N.

The change in #1133 (LWG 2567) also introduces another (possibly non-editorial) problem: does the explicit cast to bool of value mandated?

This seems non-editorial to me.

Is the program above well-formed?

It's undefined, because it fails to meet the Requires: precondition.

Then bool(Bj::value) is not appropriate as it suggests the cast shall be supported, as implemented in cppreference.

The cast is supported, but it's not required. If an implementation wants to rely on an implicit conversion instead that's fine (as long as it does so without a narrowing conversion, as per lwg 2587).

Otherwise, libstdc++, libc++ and MSVC currently all has the bug concerned with the resolution of LWG 2567

That's not an editorial issue with the standard.

@FrankHB
Copy link
Contributor Author

FrankHB commented Dec 3, 2018

What is "the instantiation of Bj::value"?

It seems clear to me.

Maybe it would be more precise to say "does not require the definition of the static data member Bj::value to exist" with a cross-reference to [temp.inst]. (Done in #2550)

Neither Bj nor Bj::value is required to be a template. The former is a template parameter, and the latter is a data member. So what is the instantiation? (I can suppose the intent, though.)

As of the modification done in #2550, is a declaration here same to a definition?

@FrankHB
Copy link
Contributor Author

FrankHB commented Dec 3, 2018

(The font of j should also be fixed.)

I'm not sure what you mean by "fixed" but I've submitted #2549 to use math mode for the subscripts i, j, 1 and N.

Yes.

The change in #1133 (LWG 2567) also introduces another (possibly non-editorial) problem: does the explicit cast to bool of value mandated?

This seems non-editorial to me.

Is the program above well-formed?

It's undefined, because it fails to meet the Requires: precondition.

I don't see any precondition prefixed Requires: in this subclause.

A non-editorial question: why not make it ill-formed?

Then bool(Bj::value) is not appropriate as it suggests the cast shall be supported, as implemented in cppreference.

The cast is supported, but it's not required. If an implementation wants to rely on an implicit conversion instead that's fine (as long as it does so without a narrowing conversion, as per lwg 2587).

Otherwise, libstdc++, libc++ and MSVC currently all has the bug concerned with the resolution of LWG 2567

That's not an editorial issue with the standard.

@jwakely
Copy link
Member

jwakely commented Dec 3, 2018

I don't see any precondition prefixed Requires: in this subclause.

Right. It's still a requirement though, and your program doesn't meet it. Please take non-editorial questions to the right place.

@FrankHB
Copy link
Contributor Author

FrankHB commented Dec 3, 2018

OK. Enlightened by the clauses about the editorial style, I think now I'm clear what happens.

As per [structure.specifications], Requires: is for "descriptions of function semantics" so I guess it is not fit here. Instead [structure.requirements] is used. As a result, [res.on.requirements] takes effect instead of [res.on.required]. Thus, the program is actually ill-formed without diagnostics required, but not undefined.

@timsong-cpp
Copy link
Contributor

The cast is supported, but it's not required. If an implementation wants to rely on an implicit conversion instead that's fine (as long as it does so without a narrowing conversion, as per lwg 2587).

My understanding is that you have to cast: implicit and explicit conversion could yield different results, and the cast was intended to pin down the behavior.

I would not be opposed to saying that "the type of Bi::value shall model ConvertibleTo<bool>" though (which imposes a requirement that the two conversions do the same thing). But this is not the right place for that discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants