0

I am kind of stuck in pre C++ 11 land. How can I write a function that takes n strings and appends them to an ostreamstream?

void Foo(std::string first_part, ...){
    std::ostringstream oss;
    oss << first_part << ...; // cant do it
    for(int i = 0; i < ....length(); i++){ // :|
    }
}

If I lived in a perfect world I could do the above. Is there any other way pre C++ 11 to loop through the ... arguments?

ICU_
  • 159
  • 1
  • 8
  • Why are you using variadic arguments? – David G Dec 21 '18 at 20:47
  • Do you have an upper limit on how many parameters you'll accept? – NathanOliver Dec 21 '18 at 20:47
  • @0x499602D2 Why not? .. – ICU_ Dec 21 '18 at 20:48
  • @NathanOliver No, not really. – ICU_ Dec 21 '18 at 20:48
  • 1
    https://en.cppreference.com/w/cpp/utility/variadic – Robert Andrzejuk Dec 21 '18 at 20:48
  • 2
    Because there are better ways do to what you want (i.e `std::vector`). – David G Dec 21 '18 at 20:48
  • 1
    Are you sure you are not confusing C++11 variadic templates (https://en.cppreference.com/w/cpp/language/parameter_pack) with pure C variadic functions (https://en.cppreference.com/w/c/variadic) ? These may look similar, but are totally different. – lisyarus Dec 21 '18 at 20:53
  • Also, I remember there being a clause in the C++ standard that variadic functions are not safe for types that are not POD types. Need to go find it... – PaulMcKenzie Dec 21 '18 at 20:57
  • You said you have no upper limit for parameter count, but are you sure? Is 50 enough? 100? Generating 50-100 thin wrapper functions seems like a plausible solution (if you really have to). You could even use Boost.Preprocessor for that, removing the need for external tools. – HolyBlackCat Dec 21 '18 at 21:03
  • If you break this down, youi'll be fine: `int cppmain(const std::string& program, const std::vector& args) { return 0; } int main(int argc, char* argv[]) { return cppmain(argv[0], {argv+1, argv+argc}); } ` – Ted Lyngmo Dec 22 '18 at 03:20

1 Answers1

1

Sorry, but it can't be done directly (at least not in portable code).

Attempting to pass a non-trivial type (including std::string) as a variadic argument gives undefined behavior.

If you want to do something similar, you could (for one example) pass the addresses of a number of strings rather than attempting to pass the strings themselves.

If you do that, you'll still have to contend with one other detail: you'll need to tell the receiving function the number of (addresses of) strings to expect.

From there, the receiving function would use va_start, va_arg and va_end to retrieve the data and do it's thing with them.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111