Question

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);
Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top