How to get a name for each argument in variable arrays?

You can create a macro str(a)that will use its argument ( a) and its string name ( #a), for example:

#include <iostream>

#define str(a) #a, " ", a

int main()
{
    int i = 5;
    float f = 4.5;
    const char* s = "string";

    auto l = [] (const auto&... p) { (std::cout << ... << p) << std::endl; };

    l(str(i));
    l(str(f));
    l(str(s));
}

An example .

Is there an easy way to print a variable number of arguments added with the name of each argument? that is, implement PREPEND_EACH_ARG_WITH_HASH_ARGfrom the following:

#include <iostream>
#include <tuple>

template <typename ... Ts>
void print_all(const Ts&... ts)
{
    (std::cout << ... << ts) << std::endl;
}

#define PREPEND_EACH_ARG_WITH_HASH_ARG(...) // how to implement '#a, " ", a' here?
#define PRINT_ALL(...) print_all(PREPEND_EACH_ARG_WITH_HASH_ARG(__VA_ARGS__))

int main()
{
    auto a = 10;
    auto b = 20.1;
    auto c = "string";
    auto d = 'c';
    PRINT_ALL(a, b, c, d);
}

An example .

+6
source share
2 answers

If you can use Boost.Preprocessor , you can do this:

#define PROCESS_ONE_ELEMENT(r, unused, idx, elem) \
  BOOST_PP_COMMA_IF(idx) BOOST_PP_STRINGIZE(elem) , " " , elem

#define PRINT_ALL(...) \
  print_all(BOOST_PP_SEQ_FOR_EACH_I(PROCESS_ONE_ELEMENT, %%, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)))

[Live example]

I use %%as placholder for "unused value".

+5
source

Boost.Preprocessor - . , , , :

#include <iostream>

#define str(a) #a, " = ", a

#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...) N

#define CONCAT_IMPL( x, y ) x##y
#define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y )

// to verify, run the preprocessor alone (g++ -E):
#define PREPEND_EACH_ARG_WITH_HASH_ARG_1(a) str(a)
#define PREPEND_EACH_ARG_WITH_HASH_ARG_2(a, ...) str(a) , " ; " , PREPEND_EACH_ARG_WITH_HASH_ARG_1(__VA_ARGS__)
#define PREPEND_EACH_ARG_WITH_HASH_ARG_3(a, ...) str(a) , " ; " , PREPEND_EACH_ARG_WITH_HASH_ARG_2(__VA_ARGS__)
#define PREPEND_EACH_ARG_WITH_HASH_ARG_4(a, ...) str(a) , " ; " , PREPEND_EACH_ARG_WITH_HASH_ARG_3(__VA_ARGS__)
#define PREPEND_EACH_ARG_WITH_HASH_ARG_5(a, ...) str(a) , " ; " , PREPEND_EACH_ARG_WITH_HASH_ARG_4(__VA_ARGS__)
#define PREPEND_EACH_ARG_WITH_HASH_ARG(...) MACRO_CONCAT(PREPEND_EACH_ARG_WITH_HASH_ARG_, VA_NUM_ARGS(__VA_ARGS__)) (__VA_ARGS__) 
#define PRINT_ALL(...) print_all(PREPEND_EACH_ARG_WITH_HASH_ARG(__VA_ARGS__))

template<typename T>
void print_impl(const T& t)
{
   std::cout << t;
}

template<typename T, typename... Ts>
void print_impl(const T& t, const Ts&... ts)
{
   std::cout << t;
   print_impl(ts...);
}


template <typename ... Ts>
void print_all(const Ts&... ts)
{
   print_impl(ts...);
   std::cout << std::endl;
}

int main()
{
   auto a = 10;
   auto b = 20.1;
   auto c = "string";
   auto d = 'c';
   PRINT_ALL(a, b, c, d);
}

, VA_NUM_ARGS PREPEND_EACH_ARG_WITH_HASH_ARG_#, "" PREPEND_EACH_ARG_WITH_HASH_ARG_# __VA_ARGS__.

, , , , , .

+5

All Articles