[英]How can I convert each parameter in a variadic function template to another type and obtain its address?
This question is similar to others that have been asked here, but with a small twist. 这个问题与在这里提出的其他问题类似,但有一个小转折。 I have a regular function something like this: 我有一个像这样的常规功能:
void Bar(std::initializer_list<Base*> objects);
Now I want to create a function template that wraps each parameter in a type that derives from Base
and passes them to the function above. 现在,我想创建一个函数模板,将每个参数包装在从Base
派生的类型中,并将它们传递给上面的函数。 Something like: 就像是:
template <class... Params> void Foo(Params... parameters)
{
Bar({&Wrapper<Params>(parameters)...});
}
(The class Wrapper
is specialized for various types.) This code actually compiles in MSVC but the compiler issues a warning because I'm taking the address of an rvalue (which is disallowed by the standard). ( Wrapper
类专门用于各种类型。)该代码实际上是在MSVC中编译的,但是编译器会发出警告,因为我要使用rvalue的地址(标准不允许)。 Is there an easy, standards conformant way to achieve the same thing? 是否有一种简单,符合标准的方法来实现同一目标? (I think I can do this with tuples, integer_sequences, and a helper function, but I'd like to avoid that if possible.) (我认为我可以使用元组,integer_sequences和辅助函数来做到这一点,但我想尽可能避免这种情况。)
The issue is the Wrapper<T>
instances must exist at some address. 问题是Wrapper<T>
实例必须存在于某个地址。 The easy way to do this is to construct a std::tuple<Wrapper<Params>...>
instance. 执行此操作的简单方法是构造一个std::tuple<Wrapper<Params>...>
实例。 The annoying part is that you have to extract the contents back out using std::get<N>
. 令人讨厌的部分是您必须使用std::get<N>
提取出内容。 In C++14, std::index_sequence
exists to help you with this matter. 在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)>());
}
If your Bar
takes const Wrapper<T>*
s, another option is to use C++'s constant ref rules to your advantage. 如果您的Bar
const Wrapper<T>*
s,则另一种选择是使用C ++的常量引用规则来发挥自己的优势。
template <class... Params>
void FooImpl(const Wrapper<Params>&... parameters)
{
Bar({ (¶meters)... });
}
template <class... Params>
void Foo(Params... parameters)
{
FooImpl(Wrapper<Params>(parameters)...);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.