模板化的格式错误的非模板化方法的实例化 class
Instantiation of ill-formed non-templated method of a templated class
我正在研究 two phase name lookup. A very logical explanation shows that one of the main reasoning,因为它遵循 尽早捕获错误的 C++ 哲学。
我的问题是为什么非模板方法不遵循这种理念。为什么不检查何时以及是否调用该方法,为什么不在实例化模板 class 时检查阶段 2 中的所有非模板方法?
例如:
template <class T>
struct X {
auto foo() // non-templated (important)
{
T t{};
return t.non_existing();
}
};
int main()
{
X<int> x; // (1) this compiles OK.
// somewhere is a galaxy far far away,
// maybe deep inside some unrelated code
x.foo(); // (2) the error is here
}
如果你从不写 (2) 程序编译和运行没有任何问题,虽然 foo
对于实例化的 X<int>
是非法的。
我认为第 (1) 行应该会产生错误,无论您是否曾调用 foo
。
在编写模板化 classes 时,这可能会让错误从裂缝中溜走,直到您最终调用该有问题的方法 (2),而不是在实例化模板化 class 时得到错误(1).
还有健全性检查:如果我实例化 X<int>
(1) 但从不调用 X<int>::foo
(2),代码是否有效?还是类似于 "ill-formed, no diagnostics required"?如果是后者,那么这是更早发现错误的更多理由。
代码有效。
此功能旨在允许 std::vector
具有简单的 operator<
或 operator==
。
此运算符会尝试盲目地对其元素调用 <
或 ==
。如果它无效,一旦你在包装 vector
上调用 <
或 ==
它将无法编译。
但如果您从未这样做过,vector
也可以正常工作。
现代 C++ 建议使用 SFINAE 条件方法技术或 C++20 Requires 子句,因此 vector
只会 有 一个 ==
或 <
如果它是一个有效的操作。 None 这些技术在 vector
设计时就已经成熟,并且能够拥有模板方法 类 的方法在无效的地方是一个重要特征。
除了无效代码的早期失败之外,==
有条件地存在允许包装代码检测 ==
是否可以安全调用:古老的技术不允许这种自省。我不得不编写专门针对标准容器模板的自定义特征,以检测 <
在至少一种情况下是否可以安全调用。
我正在研究 two phase name lookup. A very logical explanation shows that one of the main reasoning,因为它遵循 尽早捕获错误的 C++ 哲学。
我的问题是为什么非模板方法不遵循这种理念。为什么不检查何时以及是否调用该方法,为什么不在实例化模板 class 时检查阶段 2 中的所有非模板方法?
例如:
template <class T>
struct X {
auto foo() // non-templated (important)
{
T t{};
return t.non_existing();
}
};
int main()
{
X<int> x; // (1) this compiles OK.
// somewhere is a galaxy far far away,
// maybe deep inside some unrelated code
x.foo(); // (2) the error is here
}
如果你从不写 (2) 程序编译和运行没有任何问题,虽然 foo
对于实例化的 X<int>
是非法的。
我认为第 (1) 行应该会产生错误,无论您是否曾调用 foo
。
在编写模板化 classes 时,这可能会让错误从裂缝中溜走,直到您最终调用该有问题的方法 (2),而不是在实例化模板化 class 时得到错误(1).
还有健全性检查:如果我实例化 X<int>
(1) 但从不调用 X<int>::foo
(2),代码是否有效?还是类似于 "ill-formed, no diagnostics required"?如果是后者,那么这是更早发现错误的更多理由。
代码有效。
此功能旨在允许 std::vector
具有简单的 operator<
或 operator==
。
此运算符会尝试盲目地对其元素调用 <
或 ==
。如果它无效,一旦你在包装 vector
上调用 <
或 ==
它将无法编译。
但如果您从未这样做过,vector
也可以正常工作。
现代 C++ 建议使用 SFINAE 条件方法技术或 C++20 Requires 子句,因此 vector
只会 有 一个 ==
或 <
如果它是一个有效的操作。 None 这些技术在 vector
设计时就已经成熟,并且能够拥有模板方法 类 的方法在无效的地方是一个重要特征。
除了无效代码的早期失败之外,==
有条件地存在允许包装代码检测 ==
是否可以安全调用:古老的技术不允许这种自省。我不得不编写专门针对标准容器模板的自定义特征,以检测 <
在至少一种情况下是否可以安全调用。