2

如果我将 aT放入 中std::any,我可以使用any_cast<T>(my_any). 但是标准(= C++17,目前处于投票阶段)是否包含一个函数,如果 oa 是则any_cast<T>(optional<any> oa)返回,否则返回?或类似的规定?nulloptnulloptstd::any_cast<T>(oa.value())

编辑:由于人们似乎在建议实现,我还将列出我现在使用的内容:

/* using magic here to select between boost/std::experimental/std versions */

template<typename T>
inline const optional<T> any_cast(const optional<any>& operand)
{
    return operand ? 
        optional<T>(any_cast<T>(operand.value())) :
        optional<T>(nullopt);
}
4

2 回答 2

1

std::optional在提案std::any提案中没有提及类似的事情。

我想使用延续函数来实现是微不足道的,因为返回类型根据可选对象的状态而有所不同:

template <typename T, typename TOptional, typename TF>
void any_cast_or_nullopt(TOptional&& o, TF&& f)
{
    if(!o) return; 
    f(std::any_cast<T>(*o));
}

在适当的地方添加static_assert和/或SFINAE以约束功能。该值*o还应根据o的值类别转发。示例用法:

int out = -1;

std::optional<std::any> x;
x = 10;

any_cast_or_nullopt<int>(x, [&out](int value)
    {
        out = value;
    });

assert(out == 10);
于 2016-10-06T15:04:46.827 回答
0

如果std::optional有一个bind(or and_then) 成员函数(即一个optional<T>接受 aT -> optional<U>并调用它或返回的函数nullopt),那么这就是您要寻找的:

std::optional<std::any>> oa;

optional<T> opt_t = oa.bind([](std::any& v) -> std::optional<T> {
    if (T* t = std::any_cast<T>(&v)) {
        return *t;
    }
    else {
        return std::nullopt;
    }
});

或者,如果你真的想直接调用any_cast<T>和处理抛出,map

optional<T> opt_t = oa.map([](std::any& v) {
    return std::any_cast<T>(v);
});

std::optional但是没有延续函数,所以你必须把它们写成非成员函数。

于 2016-10-06T15:04:45.480 回答