I want to know if it is possible to store variadic template arguments into a member variable, for example a tuple? So I can use it in another method. I want it to work something like this, see below:
class TempClass
{
public:
//How can I Store the arguments with the help of a variable?
std::tuple<Template Args?> savedArgs;
template<typename ...Args>
void SaveTheseArgs(args&& ...args)
{
//Store the arguments into a variable for later use
savedArgs = std::make_tuple<Args>(args);
//Do something with the args...
}
void OtherMethod()
{
//I want to pass it back to the same method with the same arguments.
SaveTheseArgs(savedArgs);
}
}
//I tried a struct template like this, but this actually doesn't store them unless I am doing something wrong.
template<typename... Args>
struct StoredArguments
{
std::tuple<Args...> StoredArgs;
};
I am fairly new to C++ programming. I have some experience in other languages such as C#, AS3, Java.
Assuming I read your mind right, you save the args by not saving the args.
First, write this:
void DoOperation( std::tuple<int, double, std::string> const& tup ) {
auto&& some_arg_name = std::get<0>(tup);
auto&& second_arg_name = std::get<1>(tup);
// etc
// do stuff with the args
}
typedef std::function<void(TempClass*)> saved_operation;
saved_operation BuildOperation( int a, double b, std::string s ) const {
auto tup = std::make_tuple(a,b,s);
return [tup](TempClass* self){
return self->DoOperation(tup);
};
}
DoOperation
takes a tuple, and does the operation using those arguments.
BuildOperation
takes arguments, bundles them into a tuple, and generates a saved_operation
from them.
saved_operation
is basically a saved method call. I don't store this
because by avoiding that, the default copy ctor does the right thing. Instead, you pass this
in each time you use it.
Now using the above, we implement your stuff:
saved_operation saved_op;
template<typename ...Args>
void SaveTheseArgs(args&& ...args)
{
saved_op = BuildOperation(std::forward<Args>(args)...);
saved_op(this);
}
void OtherMethod()
{
assert(saved_op);
saved_op(this);
}
A copy of the tuple
is actually stored inside the saved_operation
object, but that is an implementation detail.
The trick is we care not about the data, but rather what we will do with the data later.
I used some concrete types (the int
double
etc), but those can just as easily be template methods as well.
If you need the efficiency, a bit more care involving moving data around instead of copying can be useful. But I kept it relatively simple. If you really need a pack of any args, you might have to google the "indexes trick" to unpack the tuple of unknown content back into parameters.
In this case, std::function
is a type erasure class that erases the details of what it is constructed from, except for the fact it can be copied, destroyed, invoked with a particular signature (and also cast-back-to-source-type, which few people use).
We exploit this to "forget" the tuple
and instead just remember the operation we want to do on the tuple
.
This technique can be used in more general situations: you can type erase anything with a fixed signature, or really anything that can be boiled down to a fixed signature (which is a bit broader).
Words to search for for more on this topic include "runtime concepts" and "type erasure". Examining how std::function
can be implemented.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments