如何在转发参数到可变模板函数时添加参数值?



假设我下面有两个函数,在Foo()函数中,我如何将hw字符串打包成参数并将它们转发给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)...);
}
}

编辑我终于找到我的bug了!如果你想知道为什么hw没有被转发到Bar(),即使你做对了,请关注else分支中的Bar()。如果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)...);
}
}

这是完整的演示

您需要将hw作为std::move(hw)单独传递给Bar函数

最新更新