You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The various standard type traits querying whether a type is constructible are implemented (in both libc++ and libstdc++) as ultimately delegating to an intrinsic such as __is_constructible. This trait fails to account for default member initializers, which produce a hard error rather than returning a true/false answer when evaluating the intrinsic, and hence the trait.
Example:
#include<type_traits>template <classT>
structWrap {
Wrap() = default;
T data{}; // default member initializer
};
structNoDefault {
NoDefault(NoDefault const&) {} // non-trivial, not an aggregate
};
intmain() {
usingnamespacestd;static_assert(!is_default_constructible<Wrap<NoDefault>>::value, "bad");
}
SFINAE only applies to instantiating the declaration of a function template specialization (and a few other things not relevant here). It does not apply to triggering the implicit definition of a defaulted constructor, nor to determining whether a defaulted constructor would be implicitly deleted.
It doesn't appear to me that Clang is doing anything wrong here.
If you want this case to become valid, I think the right core issue to file would be to suggest that [class.default.ctor]/2 should say that a defaulted default constructor is defined as deleted if it's in a templated class and instantiation of any default member initializer results in an invalid type or expression in the immediate context of the instantiation. (That is, add a brand new kind of SFINAE for this case.) CWG2202 is doing something similar for default arguments, so this is not unprecedented.
Default member initializers are not parsed until the closing brace of the outermost enclosing class they're nested within -- the default member initializer for A is not parsed until we reach the end of DataWithStruct. As a consequence (in particular, because we can't compute the exception specification for the default constructor until we've parsed the default member initializers, and in general we never form a call to a function until after we know its exception specification), default construction of an A fails in the context of the type of DataWithStruct::t.
So that's not a bug.
Given the original problem is also not a bug, I'm going to resolve this INVALID. We can reopen it or open a new bug if the committee decides to do something SFINAE-like for default member initializers.
Extended Description
The various standard type traits querying whether a type is constructible are implemented (in both libc++ and libstdc++) as ultimately delegating to an intrinsic such as __is_constructible. This trait fails to account for default member initializers, which produce a hard error rather than returning a true/false answer when evaluating the intrinsic, and hence the trait.
Example:
Godbolt link for quick experimentation: https://godbolt.org/z/-D9mpA
This fails with both libc++ and libstdc++, for all dialects of C++11 and later, for all online compilers up to and including trunk.
The text was updated successfully, but these errors were encountered: