负数组索引和似乎冗余的模板使用

Negative array index and seemingly redundant template usage

本文关键字:冗余 数组 索引      更新时间:2023-10-16

我看到了这些代码行:

template< int I > struct arg
{
    arg()
    {
    }
    template< class T > arg( T const & /* t */ )
    {
        // static assert I == is_placeholder<T>::value
        typedef char T_must_be_placeholder[ I == is_placeholder<T>::value? 1: -1 ];
    }
};
template< class T > struct is_placeholder
{
    enum _vt { value = 0 };
};

什么可能是结构is_placeholder被模板化的原因,而类型名T没有在任何地方使用?

为什么T_must_be_placeholder的定义方式使它可以具有无效的大小-1。为了实现这一点,我调用了arg<1>(1),它像预期的那样给出了error: size of array is negative。是不是某种安全检查技术?如果没有进行arg<1>(1)调用,为什么编译器不报告此问题?

,

int i = 0;
char a[i == 1 ? 1 : -1]; //No error

如果完整性检查对第一个例子有效,那么为什么第二个例子会失败?

is_placeholder是一个模板,因此它可以专门为不同的T。假设我创建了一个结构体example,并希望is_placeholder<example>::value为42。我会这样做:

struct example {};
template< class T > struct is_placeholder
{
    enum _vt { value = 0 };
};
template<>
struct is_placeholder<example>
{
    enum _vt { value = 42 };
};
template< int I > struct arg
{
    arg()
    {
    }
    template< class T > arg( T const & /* t */ )
    {
        // static assert I == is_placeholder<T>::value
        typedef char T_must_be_placeholder[ I == is_placeholder<T>::value ? 1: -1 ];
    }
};
void test()
{
    auto x = arg<42>(example()); // compiles
    auto y = arg<43>(example()); // assertion
    return 0;
}

在这种情况下,T_must_be_placeholder检查is_placeholder<example>::value(我们刚刚专门化为42)是否与I相同。因此,如果I是42,它编译,但如果I是其他的,它不会编译。

尝试创建一个负大小的数组是故意阻止代码编译的一种方式,所以,是的,这可能是一个完整性检查(静态断言,正如它在注释中所说)。