Почему std :: bind не работает с std :: filesystem :: path и std :: ostream? - PullRequest
0 голосов
/ 01 июня 2018

В настоящее время я пытаюсь написать программу, которая использует std::bind с std::filesystem::path и std::ostream, оба в качестве ссылок, следующим образом:

#include <functional>
#include <filesystem>
#include <ostream>
#include <iostream>

struct Buggy{
    static void something(const std::filesystem::path &path, std::ostream &out);
    void bind();
};

void Buggy::bind(){
    auto function = std::bind(&Buggy::something, std::placeholders::_1, std::cout);
    function(std::filesystem::path("./"));
}

void Buggy::something(const std::filesystem::path &path, std::ostream &out){
    out << path.string() << std::endl;
}

int main(){
    Buggy buggy;
    buggy.bind();
}

Я ожидаю, что этот код простовыведите «./», но вместо этого он даст мне значительных ошибок в шаблонах. Почему это так?Мое использование std::bind выглядит правильным для меня.Я компилирую с g++ --std=c++17 bug4.cpp -o bug4 -lstdc++fs в Linux.

Я не могу прочитать ошибки шаблона, потому что они так смешаны с деталями реализации этой стандартной библиотеки.Я попытался скомпилировать с Clang и GCC, оба из которых дают похожие ошибки.Поиск через поисковик не дает полезных результатов.

1 Ответ

0 голосов
/ 01 июня 2018

Параметры, связанные через std::bind, копируются по умолчанию.std::cout не подлежит копированию.Вам нужно использовать std::ref.

auto function = std::bind(&Buggy::something, std::placeholders::_1, std::ref(std::cout));

Лично я бы не стал использовать std::bind и использовал вместо этого лямбда-выражение.

auto function = [](auto&& path){ return Buggy::something(path, std::cout); };
...