2

Is it possible to convert all std::string items inside a tuple to const char*?

template<typename... Ts>
std::tuple<Ts...> tup

The problem I facing is I try to print a variadic template to file

fprintf(file, std::get<Idx>(tup)...)

the first item in tup is the format string (const char* for sure), the rest are print args. The args may contain std::string. The problem is that fprintf does not take std::string. How do I convert all std::string inside the tuple to const char* and form another tuple?

The tup will not go out scope before finish the print.

Vincent Savard
  • 34,979
  • 10
  • 68
  • 73
kzhdev
  • 667
  • 5
  • 14
  • 1
    What should the lifetime of those `const char*`s be? Should they be destroyed along with the `std::string`? Should they be dynamically allocated and then deleted at some point? – TartanLlama Feb 19 '16 at 14:10
  • @TartanLlama I just update my question, that is the problem I am facing. – kzhdev Feb 19 '16 at 15:04
  • Perhaps this question can help you: http://stackoverflow.com/questions/29820104/equivalent-of-stdtransform-for-tuples or this one: http://stackoverflow.com/questions/5235246/transform-variadic-template-parameters-to-another-types – Ferruccio Feb 19 '16 at 15:13

1 Answers1

2

If we're just fprint-ing the tuple, that's not so much converting the tuple as just passing it into something else. We can use the index sequence trick to pull out the individual components:

template <class... Ts>
void fprintf_tuple(FILE* file, std::tuple<Ts...> const& tuple) {
    fprintf_tuple(file, tuple, std::index_sequence_for<Ts...>{});
}

Once we have the individual components, we just need a converter:

template <class T> T const& convert_for_printing(T const& val) { return val; }
const char* convert_for_printing(std::string const& val) { return val.c_str(); }

And then call that on everything:

template <class... Ts, std::size_t... Is>
void fprintf_tuple(FILE* file, std::tuple<Ts...> const& tuple, std::index_sequence<Is...> )
{
    fprintf(file, 
        convert_for_printing(std::get<Is>(tuple))...
        );
}
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
Barry
  • 286,269
  • 29
  • 621
  • 977