The following code
#include <string_view>
using namespace std::string_view_literals;
#include <initializer_list>
int main() {
std::initializer_list svs{
"Meow"sv,
"Woof"sv
};
}
is compiled by all GCC versions (at least from 8.2 up), but is rejected by all clang versions up to and including 18. However, clang 19 compiles it.
https://godbolt.org/z/TPzqEssMs
To me, this looks like direct-list-initialization (case 1 here).
Given that clang's behavior changed, I suspect this is a clang bug that has been fixed (and because clang now accepts it, this shouldn't be the dreaded IFNDR). Can somebody confirm or deny this? A quick search in clang issues did not find any that would appear to refer to this situation.
CTAD doesn’t treat std::initializer_list
specially, but it’s already special. In particular, its copy constructor is of course an initializer-list constructor, treated by CTAD as if we had
struct X {
template<class T>
X(); // unusable: T not deducible
template<class T>
X(std::initializer_list<T>); // if selected, use the same type as the parameter
};
X svs{
"Meow"sv,
"Woof"sv
};
While the standard doesn’t explicitly term such a constructor template an initializer-list constructor (which may be why Clang didn’t accept this for so long), implementations are evidently treating it as such, succeeding in deduction and overload resolution in the obvious way given the list-initialization.