std::vector: ne peut pas lier 'std::ostream {aka std::base ostream}' lvalue à 'std::base ostream &&'
j'ai rencontré un message d'erreur confus en essayant de faire quelque chose d'aussi simple que
std::cout << std::vector<int>{1,2,3};
qui dit
cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
int main() { std::cout << std::vector<int>{1,2,3}; }
(testé avec gcc-4.8.1 avec-std=c++11)
a donc des questions similaires comme opérateur de surcharge<<: cannot bind lvalue to ‘std::basic_ostream&& & ’ , qui est à propos d'une classe définie par l'utilisateur avec des classes imbriquées. Il y a aussi un travail autour des la réponse à cette question.
Mais je ne sais pas si cela s'applique à std::vector
. Quelqu'un peut m'expliquer pourquoi cette erreur se produit à std::vector
, et comment l'interpréter?
Merci
3 réponses
peuvent parfois prêter à confusion. Le problème est que la bibliothèque standard ne définit pas une surcharge de operator <<
pour insérer std::vector
(ou tout autre conteneur, pour cette matière) dans un std::ostream
. Donc le compilateur ne trouve pas une surcharge appropriée pour operator <<
, et signale cet échec aussi bien que possible (ce qui n'est malheureusement pas trop bon/lisible dans votre cas).
si vous voulez streamer un entier conteneur, vous pouvez utiliser std::ostream_iterator
pour cela:
auto v = std::vector<int>{1, 2, 3};
std::copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " "));
quant à savoir pourquoi vous obtenez précisément cette erreur cryptique, il aide à analyser le message d'erreur complet:
prog.cpp: In function ‘int main()’:
prog.cpp:13:37: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
std::cout << std::vector<int>{1,2,3};
^
In file included from /usr/include/c++/4.8/iostream:39:0,
from prog.cpp:3:
/usr/include/c++/4.8/ostream:602:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::vector<int>]’
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
il y a apparemment une surcharge de template de operator<<
qui prend un argument lhs de type std::ostream&&
et un argument rhs de type templated; il existe pour permettre l'insertion dans les flux temporaires. Depuis c'est un modèle, il devient le meilleur match pour l'expression dans votre code. Cependant, std::cout
est une valeur l, de sorte qu'elle ne peut pas se lier à std::ostream&&
. D'où l'erreur.
C'est un problème connu avec gcc, j'ai déposé une demande d'amélioration à ce sujet.
Le "seul" problème, c'est que la chose que vous essayez d'imprimer à la console n'a pas de operator<<
. Malheureusement, le message d'erreur n'est pas très utile. : (
soit dit en passant, la question n'a rien à voir avec les références de vector
ou des valeurs l et R. Un exemple minime:
#include <iostream>
struct A { };
int main() {
A a;
std::cout << a;
}
voir la la discussion à la demande d'amélioration pour les détails sanglants. En bref, les développeurs de gcc avait déjà essayé d'améliorer le message d'erreur, mais il s'est avéré être notoirement difficile.
Pour ce qu'il vaut, clang du message d'erreur avec la libc++ est plus clair à mon avis :
clang++ -std=c++11 -stdlib=libc++ -lc++abi main.cpp && ./a.out
main.cpp:7:15: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'A')
std::cout << a;
~~~~~~~~~ ^ ~
Ici, la première ligne indique clairement quel est le problème.
il n'y a pas de définition de operator <<
pour la classe std::vector
dans la classe std::basic_ostream
.
Ce que vous voulez est le suivant
for ( int x : std::vector<int> { 1, 2, 3 } ) std::cout << x << ' ';
std::cout << std::endl;
bien qu'il puisse être écrit plus simple
for ( int x : { 1, 2, 3 } ) std::cout << x << ' ';
std::cout << std::endl;