确定结构体是否具有特定类型的成员

determine if struct has a member of specific type

本文关键字:类型 成员 结构体 是否      更新时间:2023-10-16

假设我有一个结构体Foo,我想确定Foo里面是否有一个int

struct Foo { int a; char c; };
has_int<Foo>::value; // should be true

这是我实际想要的最基本的形式,检查特定的类型:

has_type<Foo, int>::value;

如果我知道怎么做,我可以把它转换成我的最终目标:

has_pointer<Foo>::value; // false
struct Bar { int a; void *b; };
has_pointer<Bar>::value; // true

至于我所尝试的,很难开始,我能想到的最好的是,如果我能得到一个结构体中包含的类型包,我可以写剩下的:

template <typename... Ts>
constexpr bool any_is_pointer() noexcept {
    return (... || std::is_pointer_v<Ts>);
}

我所要求的似乎是不可能的。我找不到副本,但我很惊讶我找不到,所以它可能在那里。

就像其他人说的那样,现在你想要的东西是不可能用普通的c++实现任意类型的。但是,如果您能够提供特定的编译时信息以及您需要在其定义中操作的类型,那么您可以做您想做的事情。

您可以使用boost fusion库的适配器来实现这一点,它允许您调整现有结构以成为融合容器或定义新的结构来建模融合容器。然后,您可以使用任何boost::mpl算法来执行您想要执行的编译时检查类型。

考虑这个示例,使用struct foo和所需的has_type编译时算法:

#include <boost/fusion/adapted/struct/define_struct.hpp>
#include <boost/mpl/contains.hpp>
BOOST_FUSION_DEFINE_STRUCT(
    (your_namespace), foo, 
    (int, a) 
    (char, c))
template<typename source_type, typename search_type>
struct has_type
{
    typedef typename boost::mpl::contains<source_type, search_type>::type value_type;
    static const bool value = value_type::value;
};
#include <iostream>
int main()
{
    bool foo_has_int_pointer = has_type<your_namespace::foo, int*>::value;
    bool foo_has_int = has_type<your_namespace::foo, int>::value;
    std::cout << "foo_has_int_pointer: " << foo_has_int_pointer << "n";
    std::cout << "foo_has_int: " << foo_has_int << "n";
    your_namespace::foo my_foo;
    my_foo.a = 10;
    my_foo.c = 'x';
    std::cout << "my_foo: " << my_foo.a << ", " << my_foo.c;
}

查看输出或使用这里的示例:http://ideone.com/f0Zc2M

可以看到,您使用BOOST_FUSION_DEFINE_STRUCT宏来定义struct,您希望在编译时对其成员进行操作。Fusion提供了其他几个用于定义此类结构的宏,以及用于调整已定义结构的宏。点击这里查看。

当然,你可能已经知道它的缺点了。has_type将只工作,如果source_type是一个boost::mpl/boost::融合序列。对于您来说,这意味着您希望在编译时以这种方式推断的任何类型,都需要使用宏定义或调整。如果您正在编写的库旨在为任意库用户定义的类型工作,那么这可能是不可接受的。