Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 可以使用std::any_cast有效地强制转换std::any_C++_Templates_Casting_C++17_Std - Fatal编程技术网

C++ 可以使用std::any_cast有效地强制转换std::any

C++ 可以使用std::any_cast有效地强制转换std::any,c++,templates,casting,c++17,std,C++,Templates,Casting,C++17,Std,我正在尝试使用我的库中的std::any。我以cppreference.com为例,通过以下方式实现该示例: #include <any> #include <iostream> int main() { struct example_1{ int i1; int i2; }; // any type std::any a = 1; std::cout << a.type().nam

我正在尝试使用我的库中的
std::any
。我以cppreference.com为例,通过以下方式实现该示例:

#include <any>
#include <iostream>

int main()
{
    struct example_1{
        int i1;
        int i2;
    };


    // any type
    std::any a = 1;
    std::cout << a.type().name() << ": " << std::any_cast<int>(a) << '\n';
    a = 3.14;
    std::cout << a.type().name() << ": " << std::any_cast<double>(a) << '\n';
    a = true;
    std::cout << a.type().name() << ": " << std::any_cast<bool>(a) << '\n';

    struct example_1 ex1;
    ex1.i1 = 1;
    ex1.i2 = 2;

    a = ex1;
    std::cout << a.type().name() << ": " << std::any_cast<struct example_1>(a).i1 << " ; " << std::any_cast<struct example_1>(a).i2 << '\n';

    // bad cast
    try
    {
        a = 1;
        std::cout << std::any_cast<float>(a) << '\n';
    }
    catch (const std::bad_any_cast& e)
    {
        std::cout << e.what() << '\n';
    }

    // has value
    a = 1;
    if (a.has_value())
    {
        std::cout << a.type().name() << '\n';
    }

    // reset
    a.reset();
    if (!a.has_value())
    {
        std::cout << "no value\n";
    }

    // pointer to contained data
    a = 1;
    int* i = std::any_cast<int>(&a);
    std::cout << *i << "\n";
}
在基本类型的情况下很容易,但在结构的情况下,我们将作为调用的返回
std::any.type().name()
结构的符号

我认为要将传递的
std::any
参数转换为正确的类型,如果包含子字符串“structname”或“classname”,我可以在符号字符串中搜索。但我认为这只是一个解决办法。有没有办法有效地将
std::any
转换为正确的类型


另一个问题是,如果我在我的库中使用它,我不知道传递的对象的结构或类的名称(因此我的变通方法无法工作)。有没有办法检索它并使用正确类型的
std::any_cast

这是因为将在编译期间进行优化。如果要在
运行时
上获取类型的全名,则必须
demangle
类型的名称(这不是标准名称)

假设您的类型名位于字符串变量
type\u name
中:

int demangle_status;
char* demangled_name = abi::__cxa_demangle(type_name.c_str(), nullptr, nullptr, &demangle_status;
if (demangle_status == 0)
{
    type_name = demangled_name;
    std::free(demangled_name)
}
std::cout << type_name
int-demangle\u状态;
char*demangled\u name=abi::\uuuucxa\u demangle(键入\u name.c\u str(),nullptr,nullptr,&demangle\u status;
如果(demangle_状态==0)
{
类型\名称=需求\名称;
标准::免费(demangled_名称)
}

std::cout这是因为编译过程中会进行优化。如果要在
运行时
上获取类型的全名,必须
demangle
类型的名称(这不是标准)

假设您的类型名位于字符串变量
type\u name
中:

int demangle_status;
char* demangled_name = abi::__cxa_demangle(type_name.c_str(), nullptr, nullptr, &demangle_status;
if (demangle_status == 0)
{
    type_name = demangled_name;
    std::free(demangled_name)
}
std::cout << type_name
int-demangle\u状态;
char*demangled\u name=abi::\uuuucxa\u demangle(键入\u name.c\u str(),nullptr,nullptr,&demangle\u status;
如果(demangle_状态==0)
{
类型\名称=需求\名称;
标准::免费(demangled_名称)
}

std::cout由
.type().name()
返回的值是完全由实现定义的,您对它们没有任何保证。您甚至不能保证
.type().name()
对于多个不同的类型是不同的

即使不是这样,
.type().name()
返回运行时值,并且不能使用非常量值来计算类型

C++是静态类型的。每个表达式(在模板实例化之后)在编译时都有一个固定的类型。因此,如果不知道它(可能)包含的类型,就不能使用
std::any

您可以使用
any\u cast
.type()
返回的
std::type\u info
获取
std::any
持有的类型和值(通过它在
.name()
之外提供的其他成员),仅当在编译时确定它可以在该代码位置(模板实例化后)保留有限的可能类型集时。如果不知道它在代码中给定位置(模板实例化后)保留的潜在类型,则无法获取它在该位置保留的类型或值

如果库的用户要将其类型与
std::any
一起使用,并且您确实想要提取库代码中的值,那么您需要对代码进行模板化,并且用户需要将潜在类型作为模板参数提供给它

很少有情况下使用
std::any
是有意义的。通常
std::variant
或虚拟基类接口(用户可以从中派生自己的类型)更可能是合适的工具。或者,如果实际不需要运行时多态性(我们不知道您的用例),只需编写用户可以向其提供自定义类型的模板代码就足够了



也请注意:在C++的类型名称外定义类定义或显式前向声明之前不要使用 Stult<代码>。它不需要,但如果类型查找失败,则会有意想不到的后果。

< P>由代码> > Type().NAME()返回的值。
是完全由实现定义的,您对它们没有任何保证。您甚至不能保证
.type().name()
对于多个不同的类型是不同的

即使不是这样,
.type().name()
返回运行时值,并且不能使用非常量值来计算类型

C++是静态类型的。每个表达式(在模板实例化之后)在编译时都有一个固定的类型。因此,如果不知道它(可能)包含的类型,就不能使用
std::any

您可以使用
any\u cast
.type()
返回的
std::type\u info
获取
std::any
持有的类型和值(通过它在
.name()
之外提供的其他成员),仅当在编译时确定它可以在该代码位置(模板实例化后)保留有限的可能类型集时。如果不知道它在代码中给定位置(模板实例化后)保留的潜在类型,则无法获取它在该位置保留的类型或值

如果库的用户要将其类型与
std::any
一起使用,并且您确实想要提取库代码中的值,那么您需要对代码进行模板化,并且用户需要将潜在类型作为模板参数提供给它

很少有情况下使用
std::any
是有意义的。通常
std::variant
或虚拟基类接口(用户可以从中派生自己的类型)更可能是合适的工具。或者,如果实际不需要运行时多态性(我们不知道您的用例),只需编写用户可以向其提供自定义类型的模板代码就足够了


<