1

Permit me to say that I know this question does not fit into most conventions (if any at all) but out of curiosity and love for the programming language (C++) I'll ask this question anyway. Feel free to correct me with your answers or comments below.

The Question:

"Can we make variadic functions in C++ that accept arguments of multiple (and possibly previously unknown) data types and how would it be implemented?"

Example:

JavaScript Sample

function buildArgs(... args) {
    let iterator = 0,
        length = args.length;

    for (iterator; iterator != length; iterator += 1) {
        let arg = args[iterator];
        build(arg)
    }
}

buildArgs(1); // Valid
buildArgs(1, "Hello"); // Valid
buildArgs(1, "Hello", null) // Valid

(Hypothetical) C++ Sample:

template <class... Args, typename data>
inline void buildArgs(Args... args) {
    int iterator = 0,
        length = sizeof args;

    for (iterator; iterator != length; iterator += 1) {
        data arg = args[iterator];
        build(arg);
    }
}

buildArgs(1); // Valid
buildArgs(1, "Hello"); // Valid
buildArgs(1, "Hello", NULL); // Valid

From the examples given, the arguments considered valid to the function buildArgs can be of any data type (char, int, std::string and so on) while the function buildArgs can accept any number of those valid arguments.

I've already done some minor research on variadic functions and templates in C++ but nothing I've seen has answered this question yet.

Again, I can not speak for the practicality of this feature but I would love to very much see if it is possible.

Links:

Variadic Functions with Different Types of Arguments in C: variadic functions with different types of arguments in c

Accept all Types as Argument in Function: Accept all types as argument in function

C Programming : https://en.wikibooks.org/wiki/C_Programming/stdarg.h

C++ Reference - Parameter Pack: https://en.cppreference.com/w/cpp/language/parameter_pack

C++ Reference - Fold Expressions: https://en.cppreference.com/w/cpp/language/fold

Variable Number of Arguments in C: Variable number of arguments in C++?

Conclusion:

Thank you for taking the time to read my question, and even more thanks for answering.

8
  • 2
    not everybody who knows c++ also knows javascript, thus it would help if you also describe more in detail in words what you mean by "unknown types of parameters" Commented Aug 17, 2018 at 10:14
  • 2
    It is possible, however unlike in js it doesn't turn it into an array/tuple : it's a variadic pack that you need to unpack in order to use it.
    – Vivick
    Commented Aug 17, 2018 at 10:15
  • 2
    in other words: why is variadic templates not the the answer to your question? Commented Aug 17, 2018 at 10:15
  • 4
    The last question you link to already has an example of a variadic function that takes different types of arguments. Not sure what more you want.
    – Mat
    Commented Aug 17, 2018 at 10:16
  • 3
    what you are searching for is actually not that hypothetical, but variadic templates allow you to do exatcly this: sloppy speaking unknown number, any type you like. I dont really understand what you are asking, either you didnt know variadic templates or there is something more you want that isnt clear from the question Commented Aug 17, 2018 at 10:25

3 Answers 3

2

Parameter packs are current C++ way to do it:

template<typename... Args> auto f(Args &&...args);

With packs, you can do not much but still something:

I. Store them in tuples or (when possible) arrays or initialization_lists:

auto t = std::tuple(std::forward<Args>(args)...);
CommonType a[] = {args...};
std::set<int> mySet{args...};

II. Use them as function arguments (see tuple construction above.) One pack-aware operator in C++ is sizeof...:

std::size_t currentArity = sizeof...(Args);

III. Fold packs:

bool any = (args || ...);
(std::cout << ... << args);

set::set<int> myOtherSet;
(myOtherSet.insert(args), ...);

And so forth.

0

In case of C++11 it is much more complicated: Live example.

template <typename T>
void printArgs(T &&x)
{
    std::cout << std::forward<T>(x) << " - ";
}

template <typename FirstT, typename ...Args>
void printArgs(FirstT &&first, Args&&...remaining)
{
    printArgs(std::forward<FirstT>(first));
    printArgs(std::forward<Args>(remaining)...);
}

As you can see you do not have argument iterator. Instead pseudo recursion is used.
Also something strange called perfect forwarding should be taken into account.

Here you can see live example which gives debug information

Question was:

"Can we make variadic functions in C++ that accept arguments of multiple (and possibly previously unknown) data types and how would it be implemented?

Answer is YES. Templates in C++ are instantiated when they are used. So by default they work with any type until some problem inside is encounter, for example some functionality is not available for specific type.

In example above you can define custom type, and printArgs will fail since there is no operator<<(std::ostream &, const NewType &) for new type. To solve it you have to simply provide such operator and printArgs will start working for new type.

There are other approaches like CRTP (Curiously recurring template pattern) and so on. Template topic in C++ is quite long and complex.

0

Can we make variadic functions in C++ that accept arguments of multiple (and possibly previously unknown) data types?

Yes. There are library facilities in the header <cstdarg> to make this easier.

They are:
- va_start (enables access to variadic function arguments),
- va_arg (accesses the next variadic function argument),
- va_copy (introduced in C++11 which makes a copy of the variadic function arguments,
- va_end (which ends traversal of the variadic function arguments) and
- va_list (which holds the information needed by va_start, va_arg, va_end, and va_copy).

Additionally C, Go, C#, PHP, Java, JavaScript, Python, Perl 6 support this feature.

1
  • 1
    Magic: answer with "Yes" (rest is off topic) has the highest score.
    – Marek R
    Commented Aug 17, 2018 at 11:31

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.