确定struct是否具有特定类型的成员

Rya*_*ing 5 c++ templates sfinae template-meta-programming c++11

假设我有一个结构Foo,我想确定它是否Fooint内部.

struct Foo { int a; char c; };
has_int<Foo>::value; // should be true
Run Code Online (Sandbox Code Playgroud)

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

has_type<Foo, int>::value;
Run Code Online (Sandbox Code Playgroud)

如果我知道如何做到这一点,我可以将它转换为我的最终目标:

has_pointer<Foo>::value; // false
struct Bar { int a; void *b; };
has_pointer<Bar>::value; // true
Run Code Online (Sandbox Code Playgroud)

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

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

我要求的似乎很可能是不可能的.我找不到重复,但我很惊讶,我不能这样,它可能会在那里.

Bri*_*ice 1

正如其他人所说,对于任意类型,现在使用普通 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;
}
Run Code Online (Sandbox Code Playgroud)

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

正如您所看到的,您使用 BOOST_FUSION_DEFINE_STRUCT 宏来定义struct您想要在编译时操作的成员。fusion 提供了几个其他宏来定义这样的结构,以及用于适应已经定义的结构的宏。在这里查看它们。

当然,您可能已经知道这里的缺点了。 仅当是 boost::mpl / boost::fusion 序列has_type时才有效。source_type对于您来说,这意味着您想要在编译时以这种方式推理的任何类型,您需要使用宏来定义或调整。如果您正在编写一个旨在用于任意库用户定义类型的库,这可能对您来说是不可接受的。