Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typesafe variadic function

I want to write a function that accepts a variable number of string literals. If I was writing in C, I would have to write something like:

void foo(const char *first, ...);

and then the call would look like:

foo( "hello", "world", (const char*)NULL );

It feels like it ought to be possible to do better in C++. The best I have come up with is:

template <typename... Args>
void foo(const char* first, Args... args) {
    foo(first);
    foo(args);
}

void foo(const char* first) { /* Do actual work */ }

Called as:

foo("hello", "world");

But I fear that the recursive nature, and the fact that we don't do any type checking until we get to a single argument, is going to make errors confusing if somebody calls foo("bad", "argument", "next", 42). What I want to write, is something like:

void foo(const char* args...) {
    for (const char* arg : args) {
        // Real work
    }
}

Any suggestions?

Edit: There is also the option of void fn(std::initializer_list<const char *> args), but that makes the call be foo({"hello", "world"}); which I want to avoid.

like image 324
Martin Bonner supports Monica Avatar asked May 15 '18 15:05

Martin Bonner supports Monica


1 Answers

I think you probably want something like this:

template<class... Args,
    std::enable_if_t<(std::is_same_v<const char*, Args> && ...), int> = 0>
void foo(Args... args ){
    for (const char* arg : {args...}) {
        std::cout << arg << "\n";
    }
}

int main() {
    foo("hello", "world");
}
like image 82
llllllllll Avatar answered Sep 21 '22 12:09

llllllllll