При явном построении std::initializer_list<U>
может ли быть выведен аргумент шаблона (U
) (например, с помощью дедукции аргумента шаблона класса (CTAD))?
Другими словами, я знаю, что следующие утверждения действительны:
std::initializer_list<int> x1{1, 2, 3};
std::initializer_list<int> x2 = {1, 2, 3};
auto x3 = std::initializer_list<int>{1, 2, 3};
но следующие утверждения также действительны?
std::initializer_list x1{1, 2, 3};
std::initializer_list x2 = {1, 2, 3};
auto x3 = std::initializer_list{1, 2, 3};
Компиляторы не согласны с тем, можно ли вывести аргумент шаблона std::initializer_list
:
#include <initializer_list>
struct s {
s(std::initializer_list<int>);
};
void f() {
std::initializer_list x1{1, 2, 3}; // Clang ERROR; GCC OK; MSVC OK
std::initializer_list x2 = {1, 2, 3}; // Clang ERROR; GCC OK; MSVC OK
auto x3 = std::initializer_list{1, 2, 3}; // Clang ERROR; GCC OK; MSVC OK
s x4(std::initializer_list{1, 2, 3}); // Clang ERROR; GCC ERROR; MSVC OK
s x5{std::initializer_list{1, 2, 3}}; // Clang ERROR; GCC OK; MSVC OK
s x6 = s(std::initializer_list{1, 2, 3}); // Clang ERROR; GCC OK; MSVC OK
s x7 = s{std::initializer_list{1, 2, 3}}; // Clang ERROR; GCC OK; MSVC OK
s x8 = std::initializer_list{1, 2, 3}; // Clang ERROR; GCC OK; MSVC OK
void g(std::initializer_list<int>);
g(std::initializer_list{1, 2, 3}); // Clang ERROR; GCC OK; MSVC OK
}
(Смотрите этот пример в Compiler Explorer.)
Компиляторы проверены:
- Clang версии 7.0.0 с
-std=c++17 -stdlib=libc++
и с-std=c++17 -stdlib=libstdc++
- Версия 8.3 GCC с
-std=c++17
- MSVC версия 19.16 с
/std:c++17