有条件地向基类添加一些数据成员,以派生数据成员的存在为条件

问题描述 投票:0回答:1

我想有条件地向基类添加一些数据成员,以派生数据成员的存在为条件。

在下面的例子中,

Extra
是基类模板,将在模板参数
Enable
上进行切换。

consteval
函数
enable
用于检测派生数据成员是否存在,其返回值将用于选择我们想要的
Enable
版本。

Foo
是我们要添加额外功能的基类,
Bar
是派生类型,它声明我们正在使用的启用额外功能的必需成员。

#include <iostream>

template<bool Enable>
struct Extra
{
    static constexpr bool is_enabled = false;
};

template<>
struct Extra<true>
{
    static constexpr bool is_enabled = true;

    int extra { 42 };
};

template<typename T>
consteval bool enable()
{
    if constexpr (requires { T::enable_extra; })
        return true;
    else
        return false;
}

template<typename T>
struct Foo : Extra<enable<T>()>
{
    using Base = Extra<enable<T>()>;
    using Base::is_enabled;

    void eval()
    {
        if constexpr (is_enabled)
        {
            if (static_cast<T*>(this)->enable_extra)
                std::cout << "extra=" << Base::extra << '\n';
        }
    }
};

struct Bar : Foo<Bar>
{
    const bool enable_extra = true;
};

int main()
{
    Bar b;
    b.eval();
    return 0;
}

可以说它不起作用,并且

enable<T>()
在调用它时评估为 false。

我目前的假设是,这是由于

Bar
在实例化
Foo
时不完整,因此
T::enable_extra
尚不存在,因此
if constexpr
的计算结果为 false。

我在这里尝试做的事情可能吗?我可以根据派生类中成员的存在添加基类功能吗?

c++ templates
1个回答
0
投票

我不确定这是否满足您的要求,但如果

extra
的值不需要在类中,这可能会起作用。

#include <iostream>
#include <concepts>

template<typename T>
concept has_enable_extra = requires
{
    { T::enable_extra } -> std::same_as<bool&>;
};

template <has_enable_extra T>
static constexpr int extra = 42;

template <typename T>
struct Foo
{
    void eval()
    {
        if constexpr (has_enable_extra<T>)
        {
            if (static_cast<T*>(this)->enable_extra)
                std::cout << "extra=" << extra<T> << '\n';
        }
    }
};

struct Bar : Foo<Bar>
{
    bool enable_extra = true;
};
static_assert(has_enable_extra<Bar>);

int main()
{
    Bar b;
    b.eval();
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.