Specifying one type for all arguments passed to variadic function or variadic template function w/out using array, vector, structs, etc?
You can just accept the arguments by the variadic template and let typechecking check the validity later on when they are converted.
You can check convertibility on the function interface level though, to make use of overload resolution for rejecting outright wrong arguments for example, by using SFINAE
template<typename R, typename...> struct fst { typedef R type; };
template<typename ...Args>
typename fst<void,
typename enable_if<
is_convertible<Args, ToType>::value
>::type...
>::type
f(Args...);
For your use-case if you know the steps to go from an std::array<>
to your dragon_list_t
then you have already solved it though according to the first option above ("convert-later"):
template<typename ...Items>
dragon_list_t make_dragon_list(Items... maidens) {
std::array<Maiden, sizeof...(Items)> arr = {{ maidens ... }};
// here be dragons
}
If you combine this with the above is_convertible
approach you have a reject-early template that also does overload resolution on arguments and rejects them if not applicable.
How to get the element type of each container passed to variadic template function
You'd have to do something like:
template<typename ...T>
void foo(T...args) {
auto f = [](auto x){
using U = typename decltype(x)::value_type;
int size = sizeof(U);
int var = sizeof(U);
};
(f(args),...);;
}
If later on you'd like to change the lambda to accept references, such as f = [](auto&& x)
, you'd have to use std::decay_t
, since the decltype(x)
will give you a reference type, and a reference type does not have any nested type members:
template<typename ...T>
void foo(T...args) {
auto f = [](auto&& x){
using U = typename std::decay_t<decltype(x)>::value_type;
int size = sizeof(U);
int var = sizeof(U);
};
(f(args),...);;
}
Example: https://godbolt.org/z/fPr4Gh
How to set the same type for all arguments in this example?
The funny thing is that your current code already ensures that calls like
add(&vI, 10, 10.f, 20);
doesn't compile. If an argument's type is different from the vector's value type, then eventually it will become the second argument in a call like
add(&vI, 10.f, 20);
and then template argument deduction will fail because it deduces conflicting types for T
.
If you want to reduce the horrendous amount of error messages when the deduction failure happens deep in the recursion, SFINAE or static_assert
can help. I personally prefer Columbo's trick:
template<bool...> class bool_pack;
template<bool...b>
using all_true = std::is_same<bool_pack<true, b...>, bool_pack<b..., true>>;
template <class T, class... T2>
void add(vector<T> *v, T n, T2... rest)
{
static_assert(all_true<std::is_same<T, T2>{}...>{}, "T2 must be all Ts");
v->push_back(n);
add(v, rest...);
}
There is currently no way to avoid using both T and T2 (without modifying the call). The committee is considering potential improvements in this area, however, so something might make its way into the next standard.
With known number of args, forward variadic function in c
My question is, is it possible if I know the number of variadic args in the callee? For example, can f_wrapper be written to pass ... arguments to f?
The basic problem is that forwarding variadic arguments from one variadic function to another is a lexical issue, not a data processing issue. You must write a call to the wrapped function in which there is a compile-time representation of each argument, but you don't know until run time how many there will be, and you might not know their types.
If the space of acceptable argument lists is constrained enough, then the problem is pragmatically solvable. For example, if the wrapper will permit only a small number of variadic arguments, of only a small number of types (that it knows how to recognize), then it can analyze the variadic arguments at runtime to match them to the appropriate one of a list of possible calls to the wrapped function. Something like this:
int f_wrapper(int argc, ...) {
if (argc < 0 || argc > F_ARGS_MAX) {
// unsupported number of arguments
return -1;
}
int arg_values[F_ARGS_MAX];
// ... read argc variadic arguments into arg_values ...
switch (argc) {
case 0:
return f();
case 1:
return f(arg_values[0]);
// ...
}
}
Obviously, however, that gets impractical rather quickly, and it can't cope at all if there is no upper bound on the acceptable number of arguments.
As was suggested in comments, a variadic macro may be a more viable alternative, but that's not a complete substitute. For example, you cannot construct a pointer to a macro, you cannot use such a macro to provide an external interface to a function with internal linkage, the macro cannot host a static variable in the same way that a function does, ....
is there a c++ version of int..args
From C++11 and above, you can use parameter packs and store them in a std::initializer_list
:
#include <iostream>
#include <initializer_list>
template <typename ...Args>
void fun(Args const&... args) {
std::initializer_list<int> arg_list { args... };
std::cout << "Number of arguments: " << arg_list.size() << std::endl;
for (auto const& i : arg_list)
std::cout << i << " ";
std::cout << std::endl;
}
int main() {
// Calling the varargs method with different number
// of parameters
fun(100); // one parameter
fun(1, 2, 3, 4); // four parameters
fun(); // no parameter
// fun(1, ""); // Error
}
Related Topics
Removing Leading and Trailing Spaces from a String
C++ Obtaining Milliseconds Time on Linux - Clock() Doesn't Seem to Work Properly
How to Propagate Exceptions Between Threads
C/C++ Check If One Bit Is Set In, I.E. Int Variable
What Are the Pointer-To-Member Operators -≫* and .* in C++
Standard Library Sort and User Defined Types
What Is the Worst Real-World Macros/Pre-Processor Abuse You'Ve Ever Come Across
How to Convert Std::String to Lpcwstr in C++ (Unicode)
How to Create My Own Comparator For a Map
Confused When Boost::Asio::Io_Service Run Method Blocks/Unblocks
How to Easily Format My Data Table in C++
How to Calculate the Week Number Given a Date
How to Read Until Eof from Cin in C++
Looking For C++ Stl-Like Vector Class But Using Stack Storage