Est-ce un comportement défini de combiner une transformation qui crée des objets avec une transformation qui extrait les attributs de ces objets par référence constante ? Le code suivant ne fonctionne pas comme prévu dans Visual Studio 16.10.2, mais semble fonctionner avec gcc 11.1.
#include <array>
#include <iostream>
#include <ranges>
#include <string>
struct A {
std::string s;
};
int main() {
auto values = std::array{"a", "b"};
// transform 1: create objects
auto objects = values | std::views::transform(
[](const auto& s) { return A{s}; }
);
// transform 2: access object attributes
auto lambdaReturningConstRef = [](const auto& a) -> const auto& { return a.s; };
auto result = objects | std::views::transform(lambdaReturningConstRef);
for (const auto& s : result) {
std::cout << s << " ";
}
}
La sortie attendue est "a b", mais la sortie réelle avec Visual Studio est vide. De plus, dans une version de build Release propre (mais pas en Debug), je reçois un avertissement C4172 concernant le retour de l'adresse d'une variable locale ou temporaire.
Ajouter un getter dans A retournant une référence constante et utiliser std::mem_fn à la place du lambda supprime complètement l'avertissement, mais ne produit toujours pas le résultat attendu. De même pour l'utilisation de &A::s au lieu du lambda.
Supprimer le type de retour explicite du lambda corrige évidemment le problème.