-1

我有一些输入,可以是简单的值或容器,包装在std::any. 我不想使用异常,所以我调用返回指针或任何值的noexcept可变参数方法。any_castnullptr

我可以验证任何可用的演员表,typeid()但我不想使用它并想找到一些替代品。一些 typetraits 方法,例如decltype,declval等等。或者干脆使用std::optional.

但在这种情况下,可选似乎仍然潮湿且不稳定。MSVC 编译器程序在运行时中断std::optional源代码的深处。

#include <optional>
#include <any>
#include <utility>

int main() {

int input = 1; 

std::initializer_list<int> input2;
input2 = {1,2,3}; 

std::any any1 = input;
std::any any2 = input2;

std::optional o1 = *std::any_cast<int>(&any1);
std::optional p2 = *std::any_cast<int>(&any2);

// **std::forward<int & __ptr64>**(...) in  _Optional_destruct_base return nullptr.

}

实际上,类型特征检查将是测试any_cast可能性的最佳方法。但我仍然对 C++ 元编程感到困惑。

4

2 回答 2

1

永远不要在不知道它非空的情况下取消引用指针。

这通常适用于所有可为空的类型;在 C++ 中,这些通常是支持一元*->.

std::optional o1 = std::any_cast<int>(&any1)?*std::any_cast<int>(&any1):std::optional<int>();

例如。

任何可空类型的取消引用都是 UB,就 C++ 标准而言,它可以工作、崩溃或做任何其他事情。

但如果您的存储类型集已关闭(不更改),也请考虑 std 变体。

于 2021-04-06T13:44:29.630 回答
1

如果您想坚持使用std::optional并且不想使用指针,我认为您可以编写自己的函数来为您执行指针检查并返回正确的std::optional,例如:

template <typename T>
std::optional<T> get_v_opt(const std::any & a)
{
    if(const T * v = std::any_cast<T>(&a))
        return std::optional<T>(*v);
    else
        return std::nullopt;
}

这里有一个如何使用此类功能的用法示例:

int main()
{
    std::any a(42);

    std::optional opt_int = get_v_opt<int>(a);
    std::optional opt_str = get_v_opt<std::string>(a);

    if(opt_int.has_value())
        std::cout << "a is an int with value: " << opt_int.value() << '\n';
    else
        std::cout << "a is not an int\n";

    if(opt_str.has_value())
        std::cout << "a is a string with value: " << opt_str.value() << '\n';
    else
        std::cout << "a is not a string\n";

    return 0;
}

输出(对于这个例子):

a 是具有值的 int:42
a 不是字符串

于 2021-04-06T13:50:05.757 回答