Pytanie typ wnioskowania z rvalue initializer_list


W poniższym kodzie

#include <initializer_list>
#include <utility>

template<typename T> void f(T&& x) {}
template<typename T> void g(std::initializer_list<T> x) {}

int main()
{
    auto   x = {0}; // OK
    auto&& y = {0}; // OK
    g(x); // OK
    g(std::move(x)); // OK
    g({0}); // OK
    f(x); // OK
    f(std::move(x)); // OK
    f({0}); // failure
    return 0;
}

rvalue initializer_list można wywnioskować za pomocą auto ale nie z template.

Dlaczego C ++ zabrania tego?


11
2017-07-05 20:14


pochodzenie


Prawdopodobnie ponieważ {0} jest traktowany jako swego rodzaju "literalny inicjator" i intuicyjnie nie można przejść od literału (lub mieć wartość rwartowania do tej, z której można przejść). - Mark B
Tęskniłeś #include <utility>, tak poza tym. - chris
@chris - masz rację. Będę edytować - a.lasram
Dlaczego komitet wprowadza tę różnicę, jest pytany to pytanie. - xskxzr


Odpowiedzi:


Uważam, że wynika to z 14.8.2.1/1:

[...] argument listy inicjalizacyjnej powoduje, że parametr jest traktowany jako kontekst niewynikający (14.8.2.5). [Przykład: [...]

template<class T> void g(T);
g({1,2,3});                    // error: no argument deduced for T

- przykład końcowy]

Teraz możesz tak myśleć auto to tylko szablonowa dedukcja argumentów, ale dla list usztywnionych auto otrzymuje specjalne traktowanie w 7.1.6.4/6:

zastępowanie wystąpień auto z nowym parametrem szablonu typu U lub, jeśli inicjatorem jest a wzmocniona lista startowa (8.5.4), z std::initializer_list<U>. [...] [Przykład:

auto x1 = { 1, 2 };   // decltype(x1) is std::initializer_list<int>

- przykład końcowy]


9
2017-07-05 20:27



musi istnieć jakiś dziwny przypadek, który sprawia, że ​​komisja traktuje specjalne traktowanie wyłącznie jako auto - a.lasram
@ a.lasram: Przypuszczam, że nie zaszkodzi na to pozwolić auto x = { 1, 2, 3 };, więc równie dobrze możesz to mieć. Z drugiej strony by prawdopodobnie boli, aby umożliwić odliczanie argumentów w szablonie (myślę o konstruktorach). - Kerrek SB