Reputation: 193
I am playing with variadic macro and template. Is there any simple way to achieve the following?
It's like std::make_tuple. How to implement make_my_class? I saw I probably need "std::decay" but I don't quite understand that. Thanks a lot in advance.
template <typename... Args>
class my_class
{
public:
my_class(Args... args)
: items_(args...)
{
}
private:
std::tuple<Args...> items_;
};
// How to fix this line?
#define CREATE_MY_CLASS(var_name, args...) my_class<decltype(args...)> var_name(args...);
// Usage:
// CREATE_MY_CLASS(xyz, 1, 2, 3)
// Target:
// my_class<decltype(1), decltype(2), decltype(3)> xyz(1, 2, 3);
Upvotes: 1
Views: 430
Reputation: 10780
What's wrong with using a function template?
template <typename ... Args>
my_class<Args...> get_my_class(Args&&...args)
{
return my_class<Args...>(std::forward<Args>(args)...);
}
auto x = get_my_class(1,2,3,4,5,6);
To use the variadic arguments of a macro requires __VA_ARGS__
and I don't know how or if you can pass that to decltype()
since you need to do something that will amount to decltype(args)...
to get a list of types of args
. The function template bypasses all of that with its implicit template deduction and the auto
keyword means you don't have to know what types are being passed to my_class
to declare a variable of the appropriate type.
Upvotes: 2
Reputation: 7357
You can do it like this:
#include <iostream>
#include <tuple>
#include <utility>
// my_class declaration
// ...
template <typename... Args>
my_class<Args...> make_my_class(Args&&... args) {
return my_class<Args...>( std::forward<Args>(args)... );
}
int main() {
auto f = make_my_class(1,2);
}
Little explaination: This works same way as std::make_pair. make_my_class is receiving rvalue refs and forwarding into my_class constructor. Return value from make_my_class should be rvalue by default too. I think there should be zero overhead in such constructing method.
Upvotes: 2