I'm writing an Option class which represents a value that may or may not exist. The if_opt function is intended to take an Option and a function which will be called on the value held in the Option, but only if the value exists.
template <class T>
class Option {
private:
    std::shared_ptr<T> m_value;
public:
    explicit operator bool()const noexcept
    {
        return (bool)m_value;
    }
    Option() = default;
    explicit Option(T value)
    {
        m_value =  std::make_shared<T>(value);
    }
    template <class U>
    friend void if_opt(Option<U>&, std::function<void(U&)>);
};
template <class T>
void if_opt(Option<T>& opt, std::function<void(T&)> f)
{
    if (opt) f(*opt.m_value);
};
I've noticed that this works if I use it like so:
Option<int> none;
Option<int> some(10);
function<void(int&)> f1 = [](int& none)
{
    cout << "This should never be reached" << endl;
};
function<void(int&)> f2 = [](int& some)
{
    cout << "The value of some is: " << some << endl;
};
if_opt(none, f1);
if_opt(some, f2);
But I'd like to be able to put the lambda expression directly in the call, but when I do:
if_opt(none, [](int&)
{
    cout << "This should never be reached" << endl;
});
if_opt(some, [](int& some)
{
    cout << "The value of some is: " << some << endl;
});
I get an error:
error: no matching function for call to 'if_opt(Option<int>&, main()::<lambda(int&)>)'
I know that the type of a lambda expression is undefined in the standard, and that it merely has to be assignable to std::function<R(T)>, so this sort of makes sense, but is there a way that I can get the lambda argument to implicitly convert to a std::function<void(T&)> so that I can define the lambda in the call to if_opt the way I attempted?
Aucun commentaire:
Enregistrer un commentaire