You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CRTP Mixin中调用可变参数基类protected成员函数的优化方案咨询

CRTP Mixin中调用基类protected成员函数的优雅实现

背景与问题

我正在为派生类构建CRTP Mixin,核心需求是:

  • 自动调用所有基类中存在的fooImpl成员函数
  • 这些基类的fooImpl必须是protected的,不能暴露给外部用户

我最初写了如下代码:

#include <iostream>
struct A {
protected:
    void fooImpl() { std::cout << "A::fooImpl"; }
};

struct C {};

template <typename... T>
struct B : T... {
    void foo() {
        auto visitor = [](auto& s) {
            if constexpr (requires { s.fooImpl(); }) 
                s.fooImpl();
        };
        (visitor(static_cast<T&>(*this)), ...);
    }
};

int main() {
    B<A, C> b;
    b.foo();
    return 0;
}

这段代码的行为不符合预期:它确实没有调用C的fooImpl(符合预期),但也没有调用A的fooImpl。我推测这是因为static_cast<T&>(*this)导致fooImpl的protected可见性被限制?这种情况是否符合C++标准的预期?另外,之前关于基类protected构造器访问的讨论是否适用于这个场景?

现有解决方案(不够优雅)

我找到了两种可行但不够理想的实现方式:

方案1:CRTP友元转发

#include <iostream>
template <typename S>
struct A {
    friend S;

private:
    void fooImpl() { std::cout << "A::fooImpl"; }
};

template <typename S>
struct C {};

template <template <typename> class... T>
struct B : T<B<T...>>... {
    void foo() {
        auto visitor = [](auto& s) {
            if constexpr (requires { s.fooImpl(); }) 
                s.fooImpl();
        };
        (visitor(static_cast<T<B<T...>>&>(*this)), ...);
    }
};

这个方案能正常工作,但要求所有基类都改成模板类并将派生类设为友元,需要大量重构现有代码,对已有类的侵入性太强。

方案2:改为public成员并通过覆盖隐藏

#include <iostream>
struct A {
public:
    void foo() { std::cout << "A::foo"; }
};

struct C {};

template <typename... T>
struct B : T... {
    void foo() {
        auto visitor = [](auto& s) {
            if constexpr (requires { s.foo(); }) 
                s.foo();
        };
        (visitor(static_cast<T&>(*this)), ...);
    }
};

这个方案也可行,但把原本需要protected的成员改成了public,依赖派生类的foo来隐藏基类的同名函数,设计上不够严谨,有点过度设计的感觉。

求助

有没有更优雅的实现方式?比如利用C++20及以后的特性,实现更少样板代码、对现有基类侵入性更低的方案?


内容的提问来源于stack exchange,提问作者rath3t

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:23:13