c++ 访问基本模板类的可选当前成员

elcex8rz  于 2023-01-06  发布在  其他
关注(0)|答案(3)|浏览(144)

假设我有一个模板类,根据模板参数的不同,它可能有也可能没有成员int x,这可以通过从一个基本模板类继承来实现,对于某些特殊化,基本模板类有一个成员int x
示例代码:

#include <iostream>

template <bool present>
struct base;

template <>
struct base<true> { int x; };

template <bool present>
struct base { };

template <bool activate>
struct A : public base<activate> {
    void print() const;
};

template <bool activate>
void A<activate>::print() const
{
    if constexpr (activate) {
        std::cout << "x = " << this->x << std::endl;
    } else {
        std::cout << "nothing" << std::endl;
    }
}

int main()
{
    A<true> a;
    a.print();
    A<false> b;
    b.print();

    return 0;
}

在上面的代码中,A<true>包含从base<true>继承的成员int x,而A<false>不包含它。
现在,由于x是一个依赖名称,为了访问它,我需要使用this->xbase<true>::x,每次使用它可能会有些麻烦,因此常见的解决方案是使用using指令,如

using base<true>::x;

A的定义中。但是,当然,只有当activate=true时,这才有意义。
是否可以(也许使用宏)仅在满足条件(此处为activate=true)时才将using base<true>::x添加到A的定义中?

wooyq4lh

wooyq4lh1#

选择性地使用当前成员是一个常见的问题,如果你不介意多重继承和一些黑客攻击,你可以通过在另一个基类中使用一个static空变量来实现:

struct Nothing {};

struct StaticNothing {
    static Nothing x;   
};

template <bool activate>
struct A : public base<activate>, StaticNothing {
    using std::conditional_t<activate, base<true>, StaticNothing>::x;
    void print() const;
};

Demo
注意std::conditional_t<>决定了x来自哪个基类,这个方法的好处是,你总是可以假设有一个x成员(静态的或非静态的),所以你可以获取它的地址,等等。

xdyibdwo

xdyibdwo2#

基于@Jarod42的注解,但使用匿名类(可选)和内联变量,以确保它在没有额外定义的情况下编译。(关于OP的此注解)

template <bool present>
struct base { constexpr static struct{} x = {}; };
template <>
struct base<true> { int x = 0; };

template <bool activate>
struct A : public base<activate> {
    using base<activate>::x;
    void print() const;
};
fiei3ece

fiei3ece3#

另一个占位符选项是使用函数,其好处是可以delete它以防止不希望的访问。

template <bool present>
struct base { constexpr void x()=delete; };

template <>
struct base<true> { int x = 0; };

template <bool activate>
struct A : public base<activate> {
    using base<activate>::x;
    void print() const{
        auto&& p = x; // fail for A<false>::print
    }
};

相关问题