模板化类的格式错误的非模板化方法的实例化
Instantiation of ill-formed non-templated method of a templated class
我正在研究两阶段名称查找。一个非常合乎逻辑的解释表明,其主要原因之一是遵循了c++ 尽可能早地捕获错误的哲学。
我的问题是,为什么非模板方法不遵循这一哲学。与其检查方法何时以及是否被调用,为什么不在模板化类实例化的阶段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
。
在编写模板化类时,这可以让错误从缝隙中溜走,直到您最终调用有问题的方法(2),而不是在实例化模板化类(1)时获得错误。
也完整性检查:是代码有效,如果我实例化X<int>
(1),但从未调用X<int>::foo
(2)?或者是"格式错误,不需要诊断"之类的问题?如果是后者,则更有理由更早地捕获错误。
代码有效。
这个特性被设计成允许像std::vector
这样的东西可以简单地写成operator<
或operator==
。
该操作符将尝试在其元素上盲目调用<
或==
。如果它无效,一旦在包装vector
上调用<
或==
,它将无法编译。
但是如果你从来没有这样做过,vector
也会工作得很好。
现代c++会建议使用SFINAE条件方法技术或c++ 20要求子句,所以vector
只有有 ==
或<
,如果它是一个有效的操作。在设计vector
的时候,这些技术都还不成熟,而拥有模板类中无效方法的能力是一个重要的特性。
在无效代码的早期失败之上,让==
有条件地存在允许包装代码检测==
是否可以安全调用:古老的技术不允许这种自省。我不得不编写专门针对标准容器模板的自定义特征,以检测<
在至少一种情况下是否可以安全调用。
- 使用动态实例化的对象填充矢量的快速方法
- 检查类是否在方法中实例化
- 从 c++ 中的实例化进程获取输出的可靠方法是什么?
- 使用包含互斥锁的类的方法实例化 cpp11 线程
- 实例化对象并调用方法,使用单行语法在 C# 或 C++ 中返回值?
- 当c++实例化方法?
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- C++ 实例化新对象时不接受继承方法默认参数值
- 实例化新类时未调用的方法
- 找不到使用 bitset 实例化模板函数的有效方法
- 无法实例化抽象类,但类不是抽象/派生方法的参数
- 有没有一种优雅的方法可以从 std::vector 实例化 boost::array
- 使用类方法而不实例化
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- C++17 单独的显式方法模板实例化声明和定义
- 如何实例化多个 set 对象来测试 Set 类的各种构造函数和方法
- 模板类方法的部分专用化或实例化
- 使用自动>decltype方法显式实例化函数
- 隐式模板方法实例化
- 用虚方法实例化类,但不进行堆分配