假设我下面有两个函数,在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函数