Reputation: 946
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.
Upvotes: 1
Views: 1765
Reputation: 26800
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.
Upvotes: 0
Reputation: 38062
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.
Upvotes: 0
Reputation: 11940
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_list
s:
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.
Upvotes: 2