将参数转发到可变参数模板函数时如何添加参数值?
假设我下面有两个函数,在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。
您可能会发现这篇文章很有帮助:
使用 std::is_same,为什么我的函数仍然不能用于 2 种类型
回答
如何添加
hw到转发列表?
简单地
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)...);
}
}
这是完整的演示