假设我下面有两个函数,在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()
的人,请注意 Bar()
在 else
分支中。如果 Bar()
根据 T
需要不同类型的参数并且代码无法编译,则编译器错误可能由 else
发出分支。正如@JeJo 提到的,我应该使用 if constexpr
代替。
您可能会发现这篇文章很有帮助: using std::is_same, why my function still can't work for 2 types
最佳答案
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)...);
}
}
这里是 complete demo
关于c++ - 将参数转发到可变参数模板函数时如何添加参数值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68752542/