Страницы

Поиск по вопросам

суббота, 14 декабря 2019 г.

cannot bind ‘T’ lvalue to ‘T&&’

#cpp #cpp11 #cpp14


Почему я не могу сделать так?

#include 
#include 
#include 

using namespace std;

template  > class Container>
void print_container(Container&& container, ostream& os) {
    os << "{ ";
    for (auto& var : container) {
        os << var << " ";
    }
    os << "}";
}

int main(int argc, char* argv[])
{
    std::vector name;
    name.push_back("Igor");
    name.push_back("Andrii");

    print_container(name, cout);
    //print_container(vector{"Igor", "Andrii"}, cout); // Работает без ошибок

    return 0;
}


Получаю ошибки: 


example.cpp:22:31: error: cannot bind ‘std::vector >’ lvalue
to ‘std::vector >&&’
     print_container(name, cout);
                               ^
example.cpp:8:6: note: initializing argument 1 of ‘void print_container(Container&&,
std::ostream&) [with Type = std::basic_string; Container = std::vector; std::ostream
= std::basic_ostream]’
 void print_container(Container&& container, ostream& os) {


    


Ответы

Ответ 1



напишите print_container(std::move(name), cout); да и по-хорошему print_container константную ссылку должна принимать, а не r-value refenece... хотя не, тут универсальная ссылка, так что норм... хотя не все-таки r-value(увидев другой ответ)

Ответ 2



Проблема в Вашем коде в том, что шаблонные шаблонные параметры не дают на выходе пробрасывающую ссылку (forwarding reference). Но, судя по всему, Вы пытаетесь её использовать без понимания зачем она нужна, т.к. в Вашем примере нет никакого кода, который бы подразумевал пробрасывание типа. Из-за вышеописанной проблемы у Вас получается функция, которая первым параметром принимает rvalue-ссылку, но Вы передаёте туда lvalue-объект, поэтому компилятор ругается. Правильным выходом в этой конкретной ситуации будет использование const Container& container в качестве аргумента функции. Ведь Вы не меняете контейнер и не передаёте его никуда: другие варианты здесь просто избыточны. Но если отвлечься от всего вышесказанного, то можно заметить ещё одно: Вам совершенно не нужен шаблонный шаблонный параметр, ведь Вы нигде не используете то, что вывели благодаря ему! Поэтому если переписать пример так: template void print_container(Container&& container, ostream& os) { os << "{ "; for (auto& var : container) { os << var << " "; } os << "}"; } , то он станет Проще. Имеющим пробрасывающую ссылку (хотя она и не нужна). Код из вопроса позволил найти баг в MSVC.

Комментариев нет:

Отправить комментарий