Reputation: 534
Suppose that I have two functions below, in the Foo()
function, how can I pack the hw
string into args and forward them to Bar()
?
I tried std::bind
but that didn't work.
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)...);
}
}
Edit: Finally I found my bug! For those of you who's wondering why hw
doesn't get forwarded to Bar()
even if you did it right, please pay attention to the Bar()
in the else
branch. If Bar()
expects different types of arguments depending on T
and the code won't compile, the compiler errors might be emitted by the else
branch. As @JeJo mentioned, I should have used if constexpr
instead.
You may find this post helpful: using std::is_same, why my function still can't work for 2 types
Upvotes: 3
Views: 487
Reputation: 32722
How to add
hw
to the forward list?
Simply
Bar<T>(hw, std::forward<Args>(args)...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
or if you want to move the hw
to Bar()
#include <utility> // std::move, std::forward
Bar<T>(std::move(hw), std::forward<Args>(args)...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
or let the compiler deduce the type T
Bar(std::move(hw), std::forward<Args>(args)...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for that, the Bar
does not required the first template argument T
template<typename... Args>
void Bar(Args&&... args)
{
// ....
}
That being said, you might want to change the normal if statement with if constexpr
for compile time branching, as follows:
#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)...);
}
}
Here is the complete demo
Upvotes: 7