繁体   English   中英

有没有办法存储多种类型的结构成员指针

[英]Is there a way to store multiple types of struct members pointers

我有这段代码,可以很好地按索引检索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;

演示

(我首先要说我同意@MarekR 的评论,你的问题可能是一个“XY 问题” ,你可能根本不想这样做......但仍然:)

这是一个有趣的挑战 - “疯狂天才”安东尼 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 年的演讲:

更好的 C++14 反射 - Antony Polukhin - Meeting C++ 2018

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

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

它也会输出你的字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM