gpt4 book ai didi

c++ - 检查类是否在继承层次结构中明确定义成员类型

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:22:59 26 4
gpt4 key购买 nike

我有一组使用成员 typedef Next 链接的类,如下:

class Y; class Z;
class X { public: typedef Y Next; };
class Y { public: typedef Z Next; };
class Z { };

我需要一种方法来获取链的最终类,从链的任何类开始。感谢accepted answer of this post ,我写了下面的代码:

// cond_type<Condition, Then, Else>::type   // selects type 'Then' if 'Condition' is true, or type 'Else' otherwise
template <bool Condition, typename Then, typename Else = void>
struct cond_type
{
typedef Then type;
};
template <typename Then, typename Else>
struct cond_type<false, Then, Else >
{
typedef Else type;
};

template <class C, typename _ = void>
struct chain
{
typedef C last;
};
template <class C>
struct chain<C, typename cond_type<false, typename C::Next>::type>
{
typedef typename chain<typename C::Next>::last last;
};

使用上面的模板chain<C>::last ,以下代码正确实例化类 Z 的 3 个对象, 正如预期的那样:

chain<X>::last z1;
chain<Y>::last z2;
chain<Z>::last z3;

但是,如果所考虑的类集形成继承层次结构,则按以下方式:

class U; class V;
class T { public: typedef U Next; };
class U : public T { public: typedef V Next; };
class V : public U { };

然后,使用模板 chain<C>::last , 与任何类 C上面的集合,例如:

chain<T>::last v;

导致以下编译错误:

1>test.cpp(88): error C3646: 'last' : unknown override specifier

我知道问题出在那个类 V继承自 typedef V Next在父类中定义 U ,导致模板的特殊形式的编译chain<V,V>而通用的应该改用 V没有成员(member)Next .

无论如何,我被困在这里,因为我需要一种有效的机制,即使在这种类层次结构的情况下也是如此。

我该怎么做?

PS:类之间的继承必须保持公开;成员类型定义必须保持公开。

最佳答案

就这么简单:

template <typename T, typename = void> struct last_t_impl
{
using type = T;
};
template <typename T> struct last_t_impl
<T, std::enable_if_t<!std::is_same_v<typename T::Next, T>>>
{
using type = typename last_t_impl<typename T::Next>::type;
};
template <typename T> using last_t = typename last_t_impl<T>::type;

用法:

last_t<T> v1;
last_t<U> v2;
last_t<V> v3;

如果您需要以上代码为 C++14(而不是 C++17)编译,请更改 std::is_same_v<A,B>std::is_same<A,B>::value .


请注意您的 typename cond_type<false, T>::type可以替换为std::void_t<T> (或 C++14 中的 std::conditional_t<false,T,void>)。但在这种情况下不需要,因为链的末端将被 SFINAE 检测到 std::is_same_v<typename T::Next, T> . (即使 T::Next 由于某种原因不存在,SFINAE 仍将启动并且 last_t<T> 将只是 T。)

关于c++ - 检查类是否在继承层次结构中明确定义成员类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48136674/

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