假设我有一个使用可变参数模板的类型:
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");
}
你尝试过吗
other->store([](auto&& ... otherArgs)
?