我使用带有标志c ++ 0x的g ++ 4.6.3(当前是ubuntu 12.04的默认软件包),但我偶然发现了这一点:
template <typename T>
inline T getValue(AnObject&)
{
static_assert(false , "this function has to be implemented for desired type");
}
编译错误:
static_assertion failed "this function has to be implemented for the desired type"
即使我还没有在任何地方调用这个函数。
它是g ++错误吗?仅当在代码中的某处调用此函数时,才应实例化该函数。
这是因为条件不以任何方式取决于模板参数。因此,编译器甚至可以在实例化该模板之前对其进行评估,如果评估结果合格,则生成关联的编译错误消息false
。
换句话说,这不是错误。尽管只有在实例化模板后才能检查很多事情,但是编译器甚至可以执行其他有效性检查。例如,这就是C ++具有两阶段名称查找的原因。编译器只是在想帮助你找到可能100%发生的错误。
即使我在代码中无处调用它,您是否也可以确认该函数得到实例化?那是你说的吗?
@StephaneRolland:该函数未实例化,仅
static_assert()
执行指令。@StephaneRolland:我不记得Alexandrescu是如何定义的,但这很有可能。毕竟,这是一种新的语言功能,而不仅仅是库。同样,如果您
foo()
在模板函数中编写对的函数调用getValue()
,并且不foo()
存在任何函数,则代码将无法编译,因为编译器知道无法以编译方式实例化该模板。@StephaneRolland:然后使用
static_assert()
,但是使条件取决于某些模板参数。使其始终产生false
要用于实例化的参数(例如static_assert(typename is_same<T, type_false>::value), "Error!")
,但要在条件中提及模板参数。这将告诉编译器:“嘿,这是一个从属名称,因此请等待实例化在评判之前...”@StephaneRolland:请注意,
static_assert(sizeof(T) == 0, "Error!")
通常将其作为另一种解决方案提出,但我认为共识是,这也可能“尽早”失败,因为编译器无需查看即可知道大小永远不会小于1T
。只是为了保持在那里。