gpt4 book ai didi

c++ - 你能在 C++ 元编程中的 "hop"之间 "linked classes"吗?

转载 作者:行者123 更新时间:2023-12-05 01:04:09 25 4
gpt4 key购买 nike

假设你有这样的东西:

template<class D>
class HasDef {
public:
typedef D Def;
};

class A : public HasDef<class B> {};
class B : public HasDef<class C> {};
class C {};

所以它就像一个“元编程链表”,带有类型链接,通过包含的 typedef Def .现在我想制作一个模板“叶子”,当应用于 A ,点击链接以获取 C :

void f() {
Leaf<A>::type v; // has type C
}

甚至有可能做到这一点吗?我用 std::compare 尝试了一些方法和类似的,但没有一个是有效的代码:一切似乎都遇到了C的问题没有Def typedef,否则类型 Leaf<>当进行内部递归“调用”时,它本身是不完整的,因此它(或其内部类型 type )无法被引用。

FWIW,我想要这个的原因是为了制作一个“分层状态机”,其中 Def表示层次结构中每个状态的默认状态,并且更详细一点,这似乎为它提供了相当整洁和干净的“用户界面语法”。

最佳答案

我不太喜欢现代代码中的 f(...),因此我的版本使用 C++17 中的 void_t:

#include <type_traits>

template<class D>
struct HasDef {

typedef D Def;
};

struct A : HasDef<class B> {};
struct B : HasDef<class C> {};
struct C {};


template <typename T, typename=void>
struct DefPresent : std::false_type{};

template <typename T>
struct DefPresent<T, std::void_t<typename T::Def>> : std::true_type{};


template<typename T, bool deeper = DefPresent<T>::value>
struct Leaf
{
using Type = typename Leaf<typename T::Def>::Type;
};

template<typename T>
struct Leaf<T, false >
{
typedef T Type;
};



static_assert(std::is_same<typename Leaf<C>::Type, C>::value, "C");
static_assert(std::is_same<typename Leaf<B>::Type, C>::value, "B");
static_assert(std::is_same<typename Leaf<A>::Type, C>::value, "A");

https://godbolt.org/z/5h5rfe81o

编辑:仅出于完整性考虑,使用概念的 2 个 C++20 变体。在 GCC 10 上测试

#include <type_traits>
#include <concepts>

template<class D>
struct HasDef {
typedef D Def;
};

struct A : HasDef<class B> {};
struct B : HasDef<class C> {};
struct C {};

template <typename T>
concept DefPresent = requires(T a)
{
typename T::Def;
};

template<typename T>
struct Leaf
{
using Type = T;
};


template<typename T>
requires DefPresent<T>
struct Leaf<T>
{
using Type = Leaf<typename T::Def>::Type;
};


static_assert(std::is_same_v<typename Leaf<C>::Type, C>, "C");
static_assert(std::is_same_v<typename Leaf<B>::Type, C>, "B");
static_assert(std::is_same_v<typename Leaf<A>::Type, C>, "A");


template<typename T>
struct Leaf2
{
template <typename M>
static M test(M&&);

template <DefPresent M>
static auto test(M&&) -> typename Leaf2<typename M::Def>::Type;

using Type = decltype(test(std::declval<T>()));
};

static_assert(std::is_same<typename Leaf2<C>::Type, C>::value, "C");
static_assert(std::is_same<typename Leaf2<B>::Type, C>::value, "B");
static_assert(std::is_same<typename Leaf2<A>::Type, C>::value, "A");

https://godbolt.org/z/vcqEaPrja

关于c++ - 你能在 C++ 元编程中的 "hop"之间 "linked classes"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72875270/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com