range-v3, как действовать :: присоединиться с разделителем

Я получаю range-v3 для MSVC от git. И скомпилировать компилятором MSVC C++14.

Рассмотрим код:

auto getter2 = [](const std::string&r) { return r+r; };
std::vector<std::string> vv = { "11","22", "33" };
std::cout << (vv | view::transform(getter2) | action::join) << std::endl;

Он работает так, как ожидалось. Но я хочу добавить разделитель для присоединения, и если я напишу

std::cout << (vv | view::transform(getter2) | action::join(",")) << std::endl;

Код не компилируется. Что случилось? Масса ошибок компилятора ниже:

1>d:\sources\ranges_test\ranges_test.cpp(28): error C2672: 'operator __surrogate_func': no matching overloaded function found
1>d:\sources\ranges_test\ranges_test.cpp(28): error C2783: 'unknown-type ranges::v3::action::action<ranges::v3::action::join_fn>::operator ()(Rng &,Rest &&...) const': could not deduce template argument for '__formal'
1>d:\sources\fingrad\dev.fingrad\src\vc\lib\range\v3\action\action.hpp(120): note: see declaration of 'ranges::v3::action::action<ranges::v3::action::join_fn>::operator ()'
1>d:\sources\ranges_test\ranges_test.cpp(28): error C2893: Failed to specialize function template 'unknown-type ranges::v3::action::action<ranges::v3::action::join_fn>::operator ()(T &&,Rest &&...) const'
1>d:\sources\ranges_test\ranges_test.cpp(28): note: With the following template arguments:
1>d:\sources\ranges_test\ranges_test.cpp(28): note: 'T=const char (&)[2]'
1>d:\sources\ranges_test\ranges_test.cpp(28): note: 'Rest={}'
1>d:\sources\ranges_test\ranges_test.cpp(28): note: 'A=ranges::v3::action::join_fn'

ОБНОВЛЕНИЕ

Не только поведение порта MSVC, но и здесь


person Alexey Subbota    schedule 22.01.2018    source источник


Ответы (1)


Догадка: строковый литерал не является диапазоном. Попробуйте вместо этого передать std::string(",") или view::c_str(",") в view::join.

ОБНОВЛЕНИЕ: Ах. Вместо этого попробуйте это (проверено с помощью clang trunk):

#include <range/v3/all.hpp>
#include <vector>
#include <iostream>
int main()
{
    using namespace ranges;
    std::vector<std::string> vv = { "11","22", "33" };
    auto getter2 = [](auto&r) { return view::concat(r, r); };

    std::cout << (vv | view::transform(getter2) 
                     | view::join(',')
                     | to_<std::string>()) << std::endl;
    return 0;
}
person Eric Niebler    schedule 22.01.2018
comment
К сожалению, это не работает. Я добавил исполняемый образец в вопрос. - person Alexey Subbota; 23.01.2018
comment
Обновленный ответ. - person Eric Niebler; 23.01.2018
comment
Спасибо за ответ, это действительно работает, но проблема в том, что мне действительно не нужно concat (это только образец), и мой геттер возвращает временную строку. Я думаю, что «присоединение» не для моей цели. - person Alexey Subbota; 24.01.2018
comment
Обратите внимание, что это решение не работает, если нет возможности составить/сгенерировать нужные временные строки с помощью API представления. Например, вызов сторонней функции в качестве параметра преобразования. Есть ли какое-либо техническое ограничение, которое не позволяет action::join() иметь собственный разделитель? - person Manu343726; 03.03.2019
comment
Обновите этот ответ еще раз (например, см. здесь). - person einpoklum; 20.11.2020