c++ - 如何在 C++ 中使用可变参数模板同时保持我的实现类私有(private)?

标签 c++ c++11 templates variadic-templates

#include <cstdio>

class builtin_pack
{
    long v[4];
public:
    builtin_pack ( long v1, long v2, long v3, long v4 ) : v{v1, v2, v3, v4} {}
    void builtin_op()
    {
        printf ( "%lx,%lx,%lx,%lx\n", v[0], v[1], v[2], v[3] );
    };
    template<typename Func, typename... Targs>
    void builtin_apply ( Func f, Targs ... t )
    {
        for ( int i = 0; i < 4; i++ )
        {
            v[i] = f ( t.v[i]... );
        }
    }
};

class pack : builtin_pack
{
public:
    pack ( long v1, long v2, long v3, long v4 ) : builtin_pack ( v1, v2, v3, v4 ) {}
    template<typename Func, typename... Targs>
    pack& apply ( Func f, Targs ... t )
    {
        this->builtin_apply ( f, t... );
        return *this;
    }
    void op()
    {
        this->builtin_op();
    }
};

int main()
{
    pack p1{0xff, 0x0f, 0xf0, 0x06}, p2{0x0f00, 0xf000, 0x6700, 0xff00};
    pack p3{0x12340000, 0x56780000, 0x45120000, 0xdead0000};
    p3.apply ( [] ( long i, long j, long k )->long{return i | j | k;}, p1, p2, p3 );
    p3.op();
    return 0;
}

该代码编译错误:

main.cpp:17:24: error: cannot cast 'pack' to its private base class 'builtin_pack'
            v[i] = f ( t.v[i]... );
                       ^
main.cpp:29:15: note: in instantiation of function template specialization 'builtin_pack::builtin_apply<(lambda
      at main.cpp:42:16), pack, pack, pack>' requested here
        this->builtin_apply ( f, t... );
              ^
main.cpp:42:8: note: in instantiation of function template specialization 'pack::apply<(lambda at
      main.cpp:42:16), pack, pack, pack>' requested here
    p3.apply ( [] ( long i, long j, long k )->long{return i | j | k;}, p1, p2, p3 );
       ^
main.cpp:22:14: note: implicitly declared private here
class pack : builtin_pack
             ^~~~~~~~~~~~
main.cpp:17:26: error: 'v' is a private member of 'builtin_pack'
            v[i] = f ( t.v[i]... );
                         ^
main.cpp:22:14: note: constrained by implicitly private inheritance here
class pack : builtin_pack
             ^~~~~~~~~~~~
main.cpp:5:10: note: member is declared here
    long v[4];
         ^
2 errors generated.

我想做的是使用自定义 (lambda) 函数(称为“应用”)实现映射方法。当私有(private)实现者-公共(public)包装器的层次结构不存在时,它很容易工作,因此当数组 v 刚好在类 pack 中时,它会按预期编译和运行。但是,当数据存储在私有(private)继承类中时,它不起作用。

该类的结构是一个私有(private)实现类和一个包装类,中间遇到了这个错误。

我是否以错误的方式使用了可变参数模板?或者有可用的解决方法吗?

(由于本人是C++和stackoverflow新手,英语非母语,所以表达不好请见谅,在不忘初心的前提下,欢迎对问题提出修改或建议!)

最佳答案

您的问题是,对于私有(private)继承,您无法从 pack* 转换为 builtin_pack*(即在 pack 之外)。如果你确实转换它,代码会编译,虽然我不确定这是否是你想要的:

template<typename Func, typename... Targs>
pack& apply ( Func f, Targs ... t )
{
    this->builtin_apply ( f, static_cast<builtin_pack&&>(t)... );
    return *this;
}

live demo

关于c++ - 如何在 C++ 中使用可变参数模板同时保持我的实现类私有(private)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40153292/

相关文章:

c++ - 如何动态创建转义序列?

c++ - 禁用 MSVC 警告 C4482 是否安全?

c++ - 如何将 future 转移到 lambda 表达式中

c++ - 如何在 C++ 中的 vector<int> 中获取第一个非零值的索引

C++ 嵌套 SFINAE 模板产生编译错误

c++ - 结构化绑定(bind)和引用元组

c++ - 使用 C++ 在 RHEL 7 上接收多播数据

c++ - std::function 作为 & 发送的(非)const 输入参数

模板类上的 C++ 运算符重载

c++ - 如何避免为每个成员函数重复类模板规范?