这是ISO C ++标准14.6 / 7的声明:
知道哪些名称是类型名称 允许每个模板的语法
要检查的定义。没有 诊断应发给a 模板定义,其中a 可以生成有效的专业化。 如果没有有效的专业化 为模板定义生成, 那个模板不是 实例化,模板定义 是不正确的,没有诊断 需要。如果使用的类型 非依赖名称不完整 模板的位置 已定义但在该点完成 进行实例化的时候,和 如果那种类型的完整性
影响该程序是否是 良好的形式或影响语义 该计划,该计划是 形成不良;无需诊断。 [注意:如果模板是 实例化后,将诊断出错误 根据其他规则 本标准。正是在这些时候 错误被诊断出来是一种品质 实施问题。 ]
示例:
int j;
template<class T> class X {
// ...
void f(T t, int i, char* p)
{
// diagnosed if X::f is instantiated
t = i;
// and the assignment to t is an error
// may be diagnosed even if X::f is
p = i;
// not instantiated
// may be diagnosed even if X::f is
p = j;
// not instantiated
}
void g(T t) {
// may be diagnosed even if X::g is
+;
// not instantiated
}
};
(大多数是失败的案例) 任何人都可以为这个陈述说出更多的例子..就像这个......请?
答案 0 :(得分:1)
void f<T>() "I am an ill-formed 'template definition' parameterized on T.";
允许实现接受上面作为语法错误的模板定义,并且在实际实例化之前不进行诊断。希望这能解释它。 (当然我在开玩笑,但我并不完全不严肃。它显示了上述引用文本的缺陷:没有“模板定义”可以包含“; +;”)。
关于不完整类型的另一个问题是,以下是不正确的,但不需要诊断
struct foo;
template<typename T>
void f() { foo x; }
// foo is incomplete here
struct foo { };
// foo is complete here
int main() { f<int>(); }
标准中的“无需诊断”规则授予实现以其认为合适的任何方式运行(这使得任何违反规则的程序都不需要诊断才能具有有效的未定义行为)。结果,你引用的文字真的是(恕我直言)严重的法律层次。
请参阅Confused about ill-formed templates和Compiling C++ templates as opposed to preprocessing them(数字火星成名Walter Bright)