“char(&(...))[2]”是什么意思?

“char(&(...))[2]”是什么意思?

问题描述:

我碰到下面的代码来:“char(&(...))[2]”是什么意思?

char (&f(...))[2];

我检查它的类型(使用typeid运算和C++ FILT),并得到了:

char (&(...)) [2]

但我不能理解这种类型。 [2]是抛弃我的部分。没有它,我可以在函数定义复制型,例如:

char (&f(...))

f是(至少从typeid的+ C++ FILT的输出)的相同类型为h的:

char& h(...)

+0

请发布此代码出现的完整上下文。 – 2014-10-17 19:34:16

+0

是不是引用2个函数的数组返回char和C风格的elipse? – Creris 2014-10-17 19:35:35

+3

它是一个函数,返回一个由两个字符组成的数组的引用。第二个('char(&f(...))')是一个函数,返回一个字符的引用。在第二种情况下,外括号是多余的,在这两种情况下'...'都是一个C可变参数包。 – 0x499602D2 2014-10-17 19:36:44

它是具有变化的参数数目的函数声明和返回到两种元素的字符数组的引用。

它可以通过使用typedef来声明更简单。例如

typedef char char_array[2]; 

char_array & f(...); 

可以使用cdecl和替代的任意类型的椭圆形,如int

char (&f(int)) [2] 

引出

声明f如函数(int)返回参考到阵列2的char [...]

替换回来,你有你的声明的话。

char (&f(...))[2]; 

这是返回的两个字符数组的引用函数的声明。为了在语法上正确,需要括号。否则,&将绑定到char,并且由于[2]没有意义,将会出现语法错误。

语法可以使用类型别名进行分解。例如:

using array_ref = char (&)[2]; 
array_ref f(...); 

返回对数组而不是实际数组引用的原因是因为数组无法从函数返回。不可能。您只能像函数一样返回引用或指向数组的指针。

在所有示例中,...是C variadic argument pack


,我已经看到了这种语法的唯一的地方就是它是被用来作为函数重载分辨率SFINAE的一部分。通常这个函数伴随着一个使用模板替换来检查给定类型的属性的同名重载。如果发生替换失败,则选择第二个重载(采用可变参数包的重载)作为后备。它的返回类型是成功或失败的区别。

例如,这里的特质类来检查,如果一个类型都有一个成员函数f()

template <typename T> 
struct has_f 
{ 
private: 
    using true_type = char (&)[1]; 
    using false_type = char (&)[2]; 

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

    template <typename> 
    static false_type f(...); 
public: 
    static constexpr bool value = sizeof(check<T>(0)) == 1; 
}; 

正如你所看到的,如果T有一个成员函数f(),然后返回类型的大小会1,否则2。这些天,true_typefalse_type在很大程度上被标准特征类std::true_typestd::false_type所取代,但这仅仅是一个例子来说明它的使用。