C++ 模板:尽管存在错误,但没有编译错误 [重复]

C++ template: no compile error although an error is present [duplicate]

提问人:O.T.Vinta 提问时间:8/16/2023 最后编辑:Vlad from MoscowO.T.Vinta 更新时间:8/16/2023 访问量:73

问:

有人可以用 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
};

为什么?谢谢。

C++ 类- 模板-实例化

评论

0赞 Red.Wave 8/16/2023
在使用 ODR 之前,不会对模板成员进行实例化。如果不调用该函数,则不会对其进行实例化,并且不会发生错误。add
1赞 Peter 8/16/2023
@Red.Wave“实例化”不是一个词(在英语中,或在C++命名法中)。您拼写错误的单词是 in-inttated
0赞 Red.Wave 8/17/2023
@Peter 从来不擅长拼写。这就是我成为 CTRL+V 家伙😉的原因

答:

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

— 结束示例]

这种方法可以减少编译时间。您无需为不使用的东西付费。