Conversation
There was a problem hiding this comment.
I believe this could also be used to avoid constructible_with_nested / constructible_no_brace_elision, but didn't want to touch code that didn't impact my use case.
| static consteval bool constructible() { | ||
| return []<std::size_t... is>(std::index_sequence<is...>) { | ||
| return requires { T{any(is)...}; }; | ||
| return std::is_constructible_v<T, decltype(any_but<T>(is))...>; |
There was a problem hiding this comment.
Thinking about it, we should probably use any_but for the 1-argument case, but keep using any for other cases to allow T(T, T) constructors...
…ix4d>` `CountFieldsHelper<T>` inferred the number of fields of a struct by aggregate-initializing it with as many `any` values as possible, `any` being a type that implicitly converts to anything. If `T` contains a `std::optional<U>` field, Clang will instantiate its constructor when evaluating the initializer (as its converting constructor is `constexpr`). For `Eigen::Matrix`, this is a problem as it has `explicit Matrix(const T&)`, whose implementation cannot pick an overload that matches `any`. We can use `std::is_constructible` instead, which won't lead to that instantiation. It also prevents brace elision, which makes the count exact for structs holding a nested aggregate. We have to make sure not to convert to `T` itself, or a single argument would select `T`'s copy constructor and cut the recursive search short.
40e31b2 to
96e9137
Compare
|
@gg-sr there still seem to be quite a few issues with this. Could you take another look? |
|
@liuzicheng1987 I kept trying to make it work, in vain. I think we'll keep this patch on our side since it's necessary for Sorry for the bother! |
|
@gg-sr No bother at all. Thank you for all your excellent contributions! |
CountFieldsHelper<T>inferred the number of fields of a struct by aggregate-initializing it with as manyanyvalues as possible,anybeing a type that implicitly converts to anything.If
Tcontains astd::optional<U>field, Clang will instantiate its constructor when evaluating the initializer (as its converting constructor isconstexpr). ForEigen::Matrix, this is a problem as it hasexplicit Matrix(const T&), whose implementation cannot pick an overload that matchesany.We can use
std::is_constructibleinstead, which won't lead to that instantiation. It also prevents brace elision, which makes the count more accurate for structs holding a nested aggregate.We have to make sure not to convert to
Titself, or a single argument would selectT's copy constructor and cut the recursive search short.