这个问题与此处提出的其他问题类似,但有一点小问题。我有一个像这样的常规函数:
void Bar(std::initializer_list<Base*> objects);
现在我想创建一个函数模板,它将每个参数包装在一个派生自Base
的类型中,并将它们传递给上面的函数。类似的东西:
template <class... Params> void Foo(Params... parameters)
{
Bar({&Wrapper<Params>(parameters)...});
}
(类Wrapper
专门用于各种类型。)此代码实际上在MSVC中编译,但编译器发出警告,因为我采用了右值的地址(标准不允许) 。是否有一种简单,符合标准的方式来实现同样的目标? (我想我可以使用元组,integer_sequences和辅助函数来做到这一点,但是如果可能的话,我想避免这种情况。)
答案 0 :(得分:2)
问题是Wrapper<T>
个实例必须存在于某个地址。执行此操作的简单方法是构造std::tuple<Wrapper<Params>...>
实例。令人讨厌的部分是你必须使用std::get<N>
提取内容。在C ++ 14中,std::index_sequence
可以帮助您解决这个问题。
template <class... Params, std::size_t... Idx>
void FooImpl(std::tuple<Wrapper<Params>...>& tup, std::index_sequence<Idx...>)
{
Bar({ (&std::get<Idx>(tup))... });
}
template <class... Params>
void Foo(Params... parameters)
{
std::tuple<Wrapper<Params>...> tup(Wrapper<Params>(parameters)...);
FooImpl(tup, std::make_index_sequence<sizeof...(Params)>());
}
如果您的Bar
需要const Wrapper<T>*
,则另一个选择是使用C ++的常量参考规则。
template <class... Params>
void FooImpl(const Wrapper<Params>&... parameters)
{
Bar({ (¶meters)... });
}
template <class... Params>
void Foo(Params... parameters)
{
FooImpl(Wrapper<Params>(parameters)...);
}