有没有办法使用 C++ 中的可变参数模板检索类型的内部类型?

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

假设我有一个使用可变参数模板的类型:

template <typename... Args>
struct Outer
{
  // using Inner = something that captures ...Args ???;
}

我如何定义

Inner
,以便我以后可以在一些模板化代码中的其他地方使用它,例如:

// ... some existing function accepting potentially other template arguments
template <typename... Args2>
foo(Args2 ...)
{
 // ...
};
// ... somewhere I define some specialized Outers, as examples but not limited to
using Specific1 = Outer<int, double, bool>;
using Specific2 = Outer<std::string>;
// ...
foo(Specific1::Inner... args)
// ...
foo(Specific2::Inner... args)

我主要对 C++17 感兴趣,但愿意学习,但它可以在任何其他版本的 C++ 中完成。理想情况下,我希望在不与

std::tuple
闲逛的情况下实现这一目标。

一个最小的可重现示例:

template <typename... Args>
struct Outer
{
    using Cb = std::function<void(Args...)>;

    //using Inner = Args; // this one complains "parameter pack must be expanded in this context"
    //using Inner = Args...; // this one complains "parameter pack cannot be expanded in this context"

    template<typename CbIn>
    void store(CbIn&& cb)
    {
        mCb = std::forward<CbIn>(cb);
    }

    void call(Args... args) noexcept
    {
        mCb(args...);
    }

    // cb here accepts Args... and returns OtherOuter* (specialized with different Args)
    template<typename OtherOuter, typename CbIn>
    void foo(CbIn&& cb)
    {
        store([cb{ std::forward<CbIn>(cb)}](Args... args)
        {
            OtherOuter * other = cb(std::forward<Args>(args)...);
            other->store([](/*OtherOuter::Inner*/ ... otherArgs) // what to put here if not OtherOuter::Inner ???
            {
                // do something with otherArgs
                ([&]
                {
                    std::cout << "second " << otherArgs << std::endl;
                } (), ...);
            });
            std::cout << "first " << other->mFlag << std::endl;
        });
    }

    Cb mCb;
    bool mFlag = false;
};

并使用示例:

using OuterIntBool = Outer<int, bool>;
using OuterString = Outer<std::string>;
// works
{
    OuterIntBool outerIntBool;
    outerIntBool.store([](int i, bool b)
    {
        bool isValid = i > 0 && b;
        assert(isValid);
    });
    outerIntBool.call(1, true);
}
// does not work
{
    OuterIntBool outerIntBool;
    OuterString otherString;
    outerIntBool.foo<OuterString>([&otherString](int/* i*/, bool b)
    {
        otherString.mFlag = b;
        return &otherString;
    });
    outerIntBool.call(1, true);
    otherString.call("bar");
}
c++ templates variadic-templates using
1个回答
0
投票

你尝试过吗

other->store([](auto&& ... otherArgs)

© www.soinside.com 2019 - 2024. All rights reserved.