this is my 2nd post and i tried to find as much information before posting here as i could (including the new possibility with chatgpt) to understand some more the work of variadic function. The first try runs well where i checked if the given argument list includes a sepcific typ of argument.
template<typename T, typename Arg>
auto hasType(Arg arg) -> bool {
return std::is_same<T, decltype(arg)>::value;
}
template <typename T, typename... Args>
auto hasType(Args... args) {
return (hasType<T>(args) || ...);
}
// call like
std::string thisIsATest = "this is a test";
hasType<float>(thisIsATest, "Hello, world!", 5.67, 452);
Now the next step was getting the value of the first specific argument. I created 2 new variadic methods:
// The fall back if there is none of the specific type i search
template<typename T>
auto getFirst() -> T {
throw someCustomException("Argument list not including the specific type.");
}
template<typename T, typename Arg, typename... Args>
auto getFirst(Arg arg, Args... args) -> T {
// test if arg is not the same type and call recursive the function with
// next argument
if (!(std::is_same<T, decltype(arg)>::value)) {
return getFirst<T>(args...);
}
// the arg should now match the condition to match type with T
return arg;
//-----^--- Multiple Errors like : could not convert ‘arg’ from ‘int’ to ‘std::__cxx11::basic_string<char>’ Or error: could not convert ‘arg’ from ‘double’ to ‘std::__cxx11::basic_string<char>’
}
The idea is to call getFirst like that:
std::string thisIsATest = "This is a test";
std::string thisIsAnOtherString = "This is an other string";
int intValue = 5;
double doubleValue = 28.563;
auto result = getFirst<std::string>(5, 1.2567, intValue, true, thisIsATest, doubleValue, false, 945.621, thisIsAnOtherString);
// result = thisIsATest
There are some changes i tried, like:
In the moment i'm a litle bit stucked in the hole variadic topic, where to make the necessary changes to reach the functionality or if this is reachable at all. Maybe someone can help me here.
Thanks.
Edit: There was just a little change in my local code which holds the solution from working correctly.
auto
return type deduction requires the type deduced from different return
statements to match. Yours don't. You use if constexpr
to have the false branch discarded, then there is no issue with deducing the return type:
template<typename T, typename Arg, typename... Args>
auto getFirst(Arg arg, Args... args) -> T {
if constexpr (!(std::is_same<T, decltype(arg)>::value)) {
return getFirst<T>(args...);
} else {
return arg;
}
}