什么..(省略号)作为函数原型中唯一的函数参数,C++?

What does ... (ellipsis) as one and only function parameter in a function prototype mean in C++?

本文关键字:函数 唯一 参数 C++ 原型 省略号 什么      更新时间:2023-10-16

我遇到了一个函数声明,比如:

int vsa_d(...);

...作为唯一的参数。

我知道使用省略号,我们可以引用多个对象,但是...在这里指的是什么?

  • 这是什么意思,它意味着什么?

  • 编译器对哪些...进行评估?

  • 省略号是否可以在调用函数时也用作函数参数?


我在">注释"下找到 https://en.cppreference.com/w/cpp/language/variadic_arguments:

在 C 编程语言中,省略号参数之前必须至少出现一个命名参数,因此 printz(...(; 无效。在C++中,即使传递给此类函数的参数不可访问,也允许这种形式,并且通常用作 SFINAE 中的回退重载,利用重载分辨率中省略号转换的最低优先级。

因此,它应该用于">SFINAE"中的">回退重载"之类的任何内容。

那是什么意思?

...参数在某些 SFINAE 构造中用作包罗万象。

下面是一个关于编写类型特征has_helloworld<T>来检测类型 T 是否具有成员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;
}

它的工作方式如下:如果typeof(&T::helloworld)存在并且格式正确,则在站点test<T>(0),常量0被转换为指向成员(-函数(的指针,并选择该重载。 返回类型的大小为 1。

如果typeof(&T::helloworld)不存在,则该重载不在潜在过载集中,并选择回退test(...)作为重载。 返回类型的大小为 2。

test(...)重载有一个很好的属性,即它始终是最差匹配的、最后选择的重载。 这意味着它可以在此类构造中充当"回退默认值"。

int vsa_d(...); // can take any number of arguments

在这里,vsa_d可以接受任意数量的参数。

因此,它应该用于"回退重载"之类的东西 "SFINAE"。

那是什么意思?

例:

template <typename T>
struct has_f {
template <typename U, typename = decltype(std::declval<U&>().f())>
static std::true_type foo(U);
static std::false_type foo(...);
using type = typename decltype(foo(std::declval<T>()))::type;
};
struct a {
void f(){}
};

这里foo有两个重载:

template <typename U, typename = decltype(std::declval<U&>().f())>
static std::true_type foo(U);

如果表达式decltype(std::declval<U&>().f()有效,那么无论我们调用has_f使用什么,确实都有一个函数f,并且将选择此重载。

否则,将选择非模板成员函数

static std::false_type foo(...);

因为它的优先级最低。


std::cout << std::boolalpha << has_f<a>::type();

true