¿Podremos construir contenedores con vistas en C ++ 20?

10

Los rangos están llegando a C ++ con la versión estándar C ++ 20.

Mi pregunta: ¿podremos construir contenedores de biblioteca estándar (existentes) con algún rango? Y lo más importante, ¿con vistas de rango?

Por ejemplo, esto:

#include <vector>
#include <iostream>
#include <ranges>

int main() {
    auto sq = [](int x) { return x * x; };
    std::vector<int> vec { 3, 4, 5 };
    std::vector<int> squares { std::ranges::views::transform(vec, sq) };
    for(auto i : squares) { std::cout << i << ' '; }
    std::cout << std::endl;
}

ser un programa válido que imprime 9 16 25?

Esto compila con la biblioteca Range-v3 , por lo que vale.

einpoklum
fuente
¿Relacionado? stackoverflow.com/questions/55950955/…
StoryTeller - Unslander Monica
Por StoryTeller: aparente duplicado de ¿Por qué la próxima biblioteca de Rangos no admite la inicialización de contenedores desde un rango? ¡Pero tenga en cuenta que la resolución de la boleta electoral puede cambiar la respuesta!
Davis Herring
@DavisHerring ¿Qué podría cambiar? P1206 no se consideró para 20 para empezar y no creo que haya ningún comentario NB que quede abierto aquí. P1391 fue adoptado sin el constructor de rango (a pesar del ejemplo engañoso).
Barry
@Barry: LEWG lo reenvió en Kona, pero supongo que malinterpreté el tráfico reciente del reflector al respecto.
Davis Herring
@DavisHerring Oh, extrañaba que se discutiera dos veces : me desplacé hacia abajo a la encuesta de 4-7 y pensé que eso era todo.
Barry

Respuestas:

8

Mi pregunta: ¿podremos construir contenedores de biblioteca estándar (existentes) con algún rango? Y lo más importante, ¿con vistas de rango?

No. El único componente de biblioteca estándar que es construible a partir de un rango arbitrario que cumple con los criterios correctos es std::span<T>.

La dirección con la que probablemente irá la biblioteca estándar es hacia la que también se dirige range-v3 (tenga en cuenta que el ejemplo vinculado de range-v3 sí se compila pero advierte sobre una conversión en desuso): usar un ayudante para realizar conversiones por usted:

std::vector<int> squares =
    std::ranges::views::transform(vec, sq) | std::ranges::to<std::vector>;

Una de las razones para no ir en la dirección de los constructores de rango se puede ver desde el mismo ejemplo que está utilizando:

std::vector<int> squares { std::ranges::views::transform(vec, sq) };

Considere cuán diferente es esa declaración de estos dos:

std::vector v { std::ranges::views::transform(vec, sq) };
std::vector w ( std::ranges::views::transform(vec, sq) );

vnecesariamente sería un que vector<transform_view<...>>contiene un solo transform_view, mientras wque sería un vector<int>.

Además, agregar más constructores de contenedores cuidadosamente restringidos a la biblioteca estándar no ayudará a los tipos de contenedores de terceros de todos modos, mientras que una instalación como ranges::tofunciona perfectamente bien en todos los casos.

Barry
fuente
Las declaraciones se inicializan vy me wparecen iguales. Quizás quisiste declarar wcomo a vector<int>. De lo contrario, esta es la respuesta correcta.
Eric Niebler
55
@EricNiebler Exactamente :-) Se ven iguales. Ellos no son los mismos.
Barry
Entonces, mi programa se compila pero no hará lo que creo que hace. Okay.
einpoklum
1
Gracias, CTAD ...
TC
¿Puede explicar por qué vy wson diferentes? ¿Tiene algo que ver con cómo funciona la deducción de argumentos de plantilla de constructor?
Johannes Schaub - litb