C++ 负数组索引和看似冗余的模板使用
我遇到了以下代码行:C++ 负数组索引和看似冗余的模板使用,c++,templates,boost,compiler-errors,C++,Templates,Boost,Compiler Errors,我遇到了以下代码行: 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_p
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 };
};
如果第一个示例中的健全性检查有效,那么第二个示例中的健全性检查如何失败?
是一个模板,因此它可以专门用于不同的T
。假设我创建了一个结构example
,并希望is\u placeholder::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;
}
struct-example{};
模板结构是\u占位符
{
枚举_vt{value=0};
};
模板
结构是一个占位符
{
枚举_vt{value=42};
};
模板结构参数
{
arg()
{
}
模板arg(T常量&/*T*/)
{
//静态断言I==is_占位符::值
typedef char T_必须是占位符[I==is_占位符::值?1:-1];
}
};
无效测试()
{
auto x=arg(示例());//编译
auto y=arg(示例());//断言
返回0;
}
在这种情况下,T\u must\u be\u placeholder
检查is\u placeholder::value
(我们刚才专门定义为42)是否与I
相同。所以,如果I
是42,它就编译,但是如果I
是其他任何东西,它就不会编译
试图创建一个大小为负的数组是故意阻止代码编译的一种方式,因此,是的,这可能是一种健全性检查(如注释中所述,是静态断言)。是一个占位符
是一个模板,可以专门用于不同的T
。假设我创建了一个结构example
,并希望is\u placeholder::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;
}
struct-example{};
模板结构是\u占位符
{
枚举_vt{value=0};
};
模板
结构是一个占位符
{
枚举_vt{value=42};
};
模板结构参数
{
arg()
{
}
模板arg(T常量&/*T*/)
{
//静态断言I==is_占位符::值
typedef char T_必须是占位符[I==is_占位符::值?1:-1];
}
};
无效测试()
{
auto x=arg(示例());//编译
auto y=arg(示例());//断言
返回0;
}
在这种情况下,T\u must\u be\u placeholder
检查is\u placeholder::value
(我们刚才专门定义为42)是否与I
相同。所以,如果I
是42,它就编译,但是如果I
是其他任何东西,它就不会编译
尝试创建一个大小为负的数组是故意阻止代码编译的一种方式,因此是的,这可能是一种健全性检查(如注释中所述,是静态断言)。这是一个穷人对静态断言的实现。如果不满足某些条件,将声明一个大小为负的数组,这将触发编译错误。您的上一个示例不应编译,因为数组的大小不是常量表达式。这可能是因为GCC扩展,不确定传递负大小时会发生什么。令人惊讶的是,这确实可以编译。这是一个穷人实现的静态断言。如果不满足某些条件,将声明一个大小为负的数组,这将触发编译错误。您的上一个示例不应编译,因为数组的大小不是常量表达式。这可能是因为GCC扩展,不确定传递负大小时会发生什么。令人惊讶的是,这确实可以编译。查看。关于为什么是\u占位符是模板化的?对不起,我在使用模板方面有点经验不足:|为什么不inti=0;字符a[i==1?1:-1]代码>然后失败?@SauravSahu,因为这样您就有了VLA(用于运行时已知大小的阵列的gcc扩展)。如果设置i const,您将得到一个错误,我怀疑这是因为i
不是静态已知的,这会导致在运行时在堆栈上分配一个可变大小的数组,而不是编译错误。请参阅@user634175,如果您所说的“静态已知”是指“在编译时已知”,那么您的怀疑是正确的:pAbout为什么是\u占位符
是模板化的?对不起,我在使用模板方面有点经验不足:|为什么不inti=0;字符a[i==1?1:-1]代码>然后失败?@SauravSahu,因为这样您就有了VLA(用于运行时已知大小的阵列的gcc扩展)。如果设置i const,您将得到一个错误,我怀疑这是因为i
不是静态已知的,这会导致在运行时在堆栈上分配一个可变大小的数组,而不是编译错误。请参阅@user634175,如果“静态已知”的意思是“在编译时已知”,那么您的怀疑是正确的:p