Не удалось преобразовать из заключенного в скобки списка инициализатора в кортеж std - PullRequest
0 голосов
/ 25 апреля 2018

В рамках более крупного проекта я играю с std::tuple и шаблонами;рассмотрим следующий код:

template <typename ...T> void foo(tuple<T...> t) {}
void bar(tuple<int, char> t) {}
tuple<int, char> quxx() { return {1, 'S'}; }

int main(int argc, char const *argv[])
{
    foo({1, 'S'});           // error
    foo(make_tuple(1, 'S')); // ok
    bar({1, 'S'});           // ok
    quxx();                  // ok
    return 0;
}

Согласно этот ответ C ++ 17 поддерживает инициализацию кортежа из copy-list-initialization , однако, похоже, такая поддержкаограничено, так как я получаю следующую ошибку (GCC 7.2.0):

main.cpp: In function 'int main(int, const char**)':
main.cpp:14:17: error: could not convert '{1, 'S'}' from '<brace-enclosed initializer list>' to 'std::tuple<>'
     foo({1, 'S'}); // error
                 ^

Есть ли способ использовать синтаксис в скобках в этом сценарии?

Некоторый контекст : это будет использоваться при перегрузке оператора, поэтому я думаю, что я привязан к кортежам и не могу использовать вариады, любой совет хорошо принят.

Extra :Clang 6 также жалуется

prog.cc:12:5: error: no matching function for call to 'foo'
    foo({1, 'S'});           // error
    ^~~
prog.cc:6:31: note: candidate function [with T = <>] not viable: cannot convert initializer list argument to 'tuple<>'
template <typename ...T> void foo(tuple<T...> t) {}

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Согласно этому ответу C ++ 17 поддерживает инициализацию кортежа из инициализации copy-list, однако, похоже, такая поддержка ограничена, так как я получаю следующую ошибку

Проблема в другом.

Когда вы вызываете bar({1, 'S'}), компилятор знает, что bar() получает tuple<int, char>, поэтому примите 1 как int и 'S' как char.

См. Другой пример: если вы определили

void baz (std::tuple<int> const &)
 { }

, вы можете вызвать

baz(1);

, потому что компилятор знает, что baz() получает std::tuple<int>, поэтому примите 1 для инициализацииint в кортеже.

Но с

template <typename ...T>
void foo(tuple<T...> t)
 { }

компилятор не знает типы T...;когда вы вызываете

foo({1, 'S'}); 

, какие T... типы должны выводить компилятор?

Я вижу, по крайней мере, две гипотезы: T = int, char или T = std::pair<int, char>;или также T = std::tuple<int, char>.

Какая гипотеза должна следовать за компилятором?

Я имею в виду: если вы передаете std::tuple в foo(), компилятор принимает список типов в кортежекак список T...;но если вы передаете что-то еще, компилятор должен вывести правильный std::tuple;но этот вывод, в этом случае, не является уникальным.Итак, ошибка.

0 голосов
/ 25 апреля 2018

A braced-init-list , как и {1, 'S'}, на самом деле не имеет типа.В контексте вывода шаблона вы можете использовать их только в определенных случаях - при выводе по initializer_list<T> (где T - параметр шаблона функции) или когда соответствующий параметр уже выведен чем-то другим.В этом случае ни одна из этих двух вещей не верна - поэтому компилятор не может выяснить, каким должен быть ...T.

Так что вы можете предоставить типы напрямую:

foo<int, char>({1, 'S'});

Или вы можете создать tuple самостоятельно и передать это в:

foo(std::tuple<int, char>(1, 'S')); // most explicit
foo(std::tuple(1, 'S')); // via class template argument deduction

Сегодня ClassTemplate<Ts...> может быть выведен только из выражений типа ClassTemplate<Us...> или типов, которые наследуются от чего-то подобного.Гипотетическое предложение могло бы расширить это, чтобы дополнительно попытаться выполнить вывод аргумента шаблона класса для выражения, чтобы увидеть, успешен ли этот вывод.В этом случае {1, 'S'} не является tuple<Ts...>, но tuple __var{1, 'S'} успешно выводит tuple<int, char>, чтобы это работало.Такое предложение также должно было бы решить такие проблемы, как ... что, если мы выводим ClassTemplate<T, Ts...> или какой-либо незначительный вариант, который не является тем, что допускает дедукция аргументов шаблона класса (но это то, что многие люди иногда выражали интересв состоянии сделать).

Я не знаю о таком предложении сегодня.

...