我遇到了以下几行代码:
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
被模板化的原因是什么,而typename 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
如果第一个例子的健全性检查有效,那么第二个例子如何失败?
答案 0 :(得分:0)
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
为其他内容,则不会。
尝试创建一个负数大小的数组是故意阻止代码编译的一种方式,所以是的,这可能是一个完整性检查(静态断言,正如它在评论中所说)。