I´ve came across a function declaration, like:
int vsa_d(...);
with ...
as one and only parameter.
I know that with an ellipsis, we can refer to multiple objects, but to what does the ...
refer to here?
What does that mean and for what is it meant for?
To what ...
gets evaluated by the compiler?
Could the ellipsis be used also as a function argument, at the invocation of a function?
I´ve found here https://en.cppreference.com/w/cpp/language/variadic_arguments under "Notes":
In the C programming language, at least one named parameter must appear before the ellipsis parameter, so printz(...); is not valid. In C++, this form is allowed even though the arguments passed to such function are not accessible, and is commonly used as the fallback overload in SFINAE, exploiting the lowest priority of the ellipsis conversion in overload resolution.
So, it shall be used for anything like a "fallback overload" in "SFINAE".
What does that mean?
The ...
argument is used as a catch-all in some SFINAE constructions.
Here is an excerpt from the top answer in a question about writing a type trait has_helloworld<T>
that detects whether a type T has a member helloworld
:
template <typename T>
class has_helloworld
{
typedef char one;
struct two { char x[2]; };
template <typename C> static one test( typeof(&C::helloworld) ) ;
template <typename C> static two test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(char) };
};
int main(int argc, char *argv[])
{
std::cout << has_helloworld<Hello>::value << std::endl;
std::cout << has_helloworld<Generic>::value << std::endl;
return 0;
}
It works in the following way: if typeof(&T::helloworld)
exists and is well-formed, then at the site test<T>(0)
, the constant 0
can be converted to a pointer-to-member(-function) and that overload is selected. The size of the return type is that of one char
.
If typeof(&T::helloworld)
does not exist, then that overload is not in the potential overload set, and the fallback test(...)
is selected as the overload. The size of the return type is that of two char
s.
The test(...)
overload has the nice property that it is always the worst-matching, last-selected overload. This means it can serve as the "fallback default" in such constructions.