LINUX.ORG.RU

проблемы с std::variant of lambda

 


0

3

Обмазываюсь тут 17-ми плюсами и захотелось поизвращаться.

Есть вот такой пример:

#include <iostream>
#include <variant>
#include <functional>
using namespace std;

int main( int argc, const char* argv[] ) {
    using variant1 = variant< function<void()>, function<void( optional< string > )> >;
    variant1 t1,t2;
    t1 = []() {
        cout << "t1" << endl;
    };
    t2 = []( optional<string> v ) {
        cout << v.value_or( "none!" ) << endl;
    };

    using variant2 = variant< function<void()>, function<void( optional< string > )>, function< void( string ) > >;
    variant2 t3,t4,t5;
    
    t3 = []() {
        cout << "t1" << endl;
    };

    // Вот тут ошибка компиляции
    t4 = []( optional<string> v ) {
        cout << v.value_or( "none!" ) << endl;
    };

    t5 = []( string v ){
        cout << v << endl;
    }

    return 0;
}

И получаю следующую ошибку:

/home/user/tmp/1/test1.cpp:28:2: error: no match for ‘operator=’ (operand types are ‘variant2’ {aka ‘std::variant<std::function<void()>, std::function<void(std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >)>, std::function<void(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)> >’} and ‘main(int, const char**)::<lambda(std::optional<std::__cxx11::basic_string<char> >)>’)

Понятно, что проблема решается прямым указанием типа:

    t4 = ( function<void( optional< string > )> ) []( optional<string> v ) {
        cout << v.value_or( "none!" ) << endl;
    };

Но мне интересно, в чём тут грабли. Т.е. по каким-то причинам компилятор перестал распознавать сигнатуру? Путает optional<string> и string? Или что тут такое может быть?

★★★★★

Какой компилятор, для начала?

anonymous
()

Сигнатуры тут вообще ни при чем. Коструктор std::function опирается на то можно ли вызвать Callable, который ему передали с нужными аргументами, тут возможны неявные преобразования, а string может быть передан в аргумент и типа string, и optional

Begemoth ★★★★★
()
Последнее исправление: Begemoth (всего исправлений: 1)
Ответ на: комментарий от Begemoth

Иными словами,

[code] function<void(string)> f = {}; [/code]

является правильным присваиванием.

anonymous
()
Ответ на: комментарий от Begemoth

Иными словами, присваивание

function<void(string)> f = [](optional<string>){};

является правильным присваиванием.

anonymous
()
Ответ на: комментарий от Begemoth

Меня смутила ошибка. Если компилятор не может определится, что он должен подставить, то не логично было бы что-то наподобии «ambiguous что-то там». А тут он говорит что не найден ‘operator=’, хотя у него тут два таких оператора.

WatchCat ★★★★★
() автор топика
Последнее исправление: WatchCat (всего исправлений: 1)
Ответ на: комментарий от WatchCat

А там на деле шаблон, а не два operator= + тот же SFINAE.

Begemoth ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.