提问人:O.T.Vinta 提问时间:8/16/2023 最后编辑:Vlad from MoscowO.T.Vinta 更新时间:8/16/2023 访问量:73
C++ 模板:尽管存在错误,但没有编译错误 [重复]
C++ template: no compile error although an error is present [duplicate]
问:
这个问题在这里已经有答案了:
C++ 模板未报告局部变量错误 (1 个答案)
C++ 编译器未检测到类模板中的错误 (4 个答案)
是否在不实例化 C++ 模板的情况下检查它们是否存在语法错误? (2 个答案)
3个月前关闭。
有人可以用 C++ 模板阐明一个奇怪的现象吗?请考虑以下简单代码:
class B {};
template <typename T>
class A
{
T _v;
public:
A() {}
void add(T a) { _v += a; }
};
int main()
{
A<B> b;
return 0;
}
显然这是不合法的,因为 += 运算符不是为 B 类定义的,因此方法中的代码无效。然而,这段代码编译得很好!add
直到调用该方法,才会收到编译错误:add
int main()
{
A<B> b;
b.add(B()); // complains about a missing += operator
return 0;
}
对于非模板类,无论是否使用该类,都会发生编译错误。
class C
{
B _v;
public:
C() {}
void add(B a) { _v += a; } // compile error here right away
};
为什么?谢谢。
答:
4赞
Vlad from Moscow
8/16/2023
#1
如果未使用类模板的成员函数,则不会实例化该函数。
在第二个程序中,使用类模板的成员 functon,编译器尝试实例化它。因此,它会发出错误。A
来自 C++20 标准(13.9.2 隐式实例化)
3 类模板专用化的隐式实例化导致
(3.1) — 声明的隐式实例化,但不是 未删除的类成员函数 member 的定义 类、作用域成员枚举、静态数据成员、成员 模板和朋友;和
(3.2) — deleted 定义的隐式实例化 成员函数、无作用域成员枚举和成员匿名 工会。
还有一个例子
[示例 3 :
template<class T>
struct C {
void f() { T x; }
void g() = delete;
};
C<void> c; // OK, definition of C<void>::f is not instantiated at this point
template<> void C<int>::g() { } // error: redefinition of C<int>::g
— 结束示例]
这种方法可以减少编译时间。您无需为不使用的东西付费。
评论
add