将参数转发给可变参数模板函数时如何添加参数值?
How to add a parameter value when forwarding parameters to a variadic template function?
假设我下面有两个函数,在Foo()
函数中,如何将hw
字符串打包成args并转发给Bar()
?
我试过 std::bind
但没用。
template<typename T, typename... Args>
void Bar(Args&&... args)
{
// do something with args
}
template<typename T, typename... Args>
void Foo(Args&&... args)
{
if (typeid(T) == typeid(std::string)) {
std::string hw = "Hello, world!";
Bar<T>(std::forward<Args>(hw, args)...); // how to add hw to the forward list?
}
else {
Bar<T>(std::forward<Args>(args)...);
}
}
编辑:终于找到我的错误了!对于那些想知道为什么 hw
没有被转发到 Bar()
的人,即使你做对了,请注意 else
分支中的 Bar()
。如果 Bar()
根据 T
需要不同类型的参数并且代码无法编译,则 else
分支可能会发出编译器错误。正如@JeJo 提到的,我应该使用 if constexpr
来代替。
您可能会发现此 post 有帮助:
How to add hw
to the forward list?
简单
Bar<T>(hw, std::forward<Args>(args)...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
或者如果您想将 hw
移动到 Bar()
#include <utility> // std::move, std::forward
Bar<T>(std::move(hw), std::forward<Args>(args)...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
或者让编译器推导出类型T
Bar(std::move(hw), std::forward<Args>(args)...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
为此,Bar
不需要第一个模板参数 T
template<typename... Args>
void Bar(Args&&... args)
{
// ....
}
话虽这么说,您可能想用 if constexpr
更改正常的 if 语句以进行编译时分支,如下所示:
#include <utility> // std::move, std::forward
#include <type_traits> // std::is_same_v
template<typename T, typename... Args>
void Foo(Args&&... args)
{
if constexpr (std::is_same_v<T, std::string>)
{
std::string hw = "Hello, world!";
Bar(std::move(hw), std::forward<Args>(args)...);
}
else
{
Bar(std::forward<Args>(args)...);
}
}
您需要将 hw 作为 std::move(hw) 单独传递给 Bar 函数。
假设我下面有两个函数,在Foo()
函数中,如何将hw
字符串打包成args并转发给Bar()
?
我试过 std::bind
但没用。
template<typename T, typename... Args>
void Bar(Args&&... args)
{
// do something with args
}
template<typename T, typename... Args>
void Foo(Args&&... args)
{
if (typeid(T) == typeid(std::string)) {
std::string hw = "Hello, world!";
Bar<T>(std::forward<Args>(hw, args)...); // how to add hw to the forward list?
}
else {
Bar<T>(std::forward<Args>(args)...);
}
}
编辑:终于找到我的错误了!对于那些想知道为什么 hw
没有被转发到 Bar()
的人,即使你做对了,请注意 else
分支中的 Bar()
。如果 Bar()
根据 T
需要不同类型的参数并且代码无法编译,则 else
分支可能会发出编译器错误。正如@JeJo 提到的,我应该使用 if constexpr
来代替。
您可能会发现此 post 有帮助:
How to add
hw
to the forward list?
简单
Bar<T>(hw, std::forward<Args>(args)...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
或者如果您想将 hw
移动到 Bar()
#include <utility> // std::move, std::forward
Bar<T>(std::move(hw), std::forward<Args>(args)...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
或者让编译器推导出类型T
Bar(std::move(hw), std::forward<Args>(args)...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
为此,Bar
不需要第一个模板参数 T
template<typename... Args>
void Bar(Args&&... args)
{
// ....
}
话虽这么说,您可能想用 if constexpr
更改正常的 if 语句以进行编译时分支,如下所示:
#include <utility> // std::move, std::forward
#include <type_traits> // std::is_same_v
template<typename T, typename... Args>
void Foo(Args&&... args)
{
if constexpr (std::is_same_v<T, std::string>)
{
std::string hw = "Hello, world!";
Bar(std::move(hw), std::forward<Args>(args)...);
}
else
{
Bar(std::forward<Args>(args)...);
}
}
您需要将 hw 作为 std::move(hw) 单独传递给 Bar 函数。