微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有一种方法可以存储多种类型的结构成员指针 我尝试过的事情:

如何解决有没有一种方法可以存储多种类型的结构成员指针 我尝试过的事情:

我有这段代码可以很好地按索引检索foo成员。

#include <string>
#include <iostream>

struct Foo {
    int a = 42;
    int b = 16;
    std::string str = "hi";
};

int main()
{
    int Foo::*members[] = { &Foo::a,&Foo::b };
    Foo foo;

    std::cout << foo.*members[1] << std::endl;
    return 0;
}

问题是我的结构上有一个std::string,我希望能够以相同的方式访问它,是否有可扩展到任何类型的解决方案?

我尝试过的事情:

#include <string>
#include <iostream>
#include <any>

struct Foo {
    int a = 42;
    int b = 16;
    std::string str = "coucou";
};

int main()
{
    std::any Foo::*members[] = { (std::any Foo::*)&Foo::a,(std::any Foo::*)&Foo::b,(std::any Foo::*)&Foo::str };
    Foo foo;

    std::cout << std::any_cast<int>(foo.*members[0]) << std::endl;
    return 0;
}

我告诉自己,如果存储std::any数组,那将起作用。实际上,该代码可以编译但会崩溃。

解决方案吗?

解决方法

您可以使用std::tuple

std::tuple members{&Foo::a,&Foo::b,&Foo::str }; // C++17 CTAD
                                                  // else,use `std::make_tuple`
Foo foo;

std::cout << foo.*std::get<0>(members) << " " << foo.*std::get<2>(members) << std::endl;

Demo

,

(我首先要同意@MarekR的评论,您的问题很可能是"XY problem",而您实际上根本不想这样做……但仍然:)

这是一个有趣的挑战,并且“疯狂的天才”安东尼·波卢欣(Antony Polukhin)在他的magic_get库中已解决了这一挑战-前提是您使用的是C ++ 14语言标准或更高版本。

>

实际上不需要存储任何东西!结构定义本身具有您需要的所有信息。因此,当您编写:

#include <iostream>
#include <string>

#include "boost/pfr.hpp" // <- Not formally a part of Boost,yet...
                         //    you'll need to download the library from github

struct Foo {
    int a = 42;
    int b = 16;
    std::string str = "hi";
};

int main() {
    Foo my_foo;

    std::cout 
        << "a is " << boost::pfr::get<0>(my_foo) << ","
        << "b is " << boost::pfr::get<1>(my_foo) << ","
        << "and str is \"" << boost::pfr::get<2>(my_foo) << "\".\n";
}

您得到:

a is 42,b is 16,and str is "hi".

就像您想要的那样。

要了解到底发生了什么以及这种黑魔法来自何处,请观看安东尼在2018年的讲话:

Better C++14 reflections - Antony Polukhin - Meeting C++ 2018

,

尽量不要在结构体内部使用string作为指针,因为它不会指向任何内容。相反,您可以像这样简单地使用:

    std::cout << foo.str << std::endl;

它也会输出您的字符串。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。