这段代码在C++中是否合法

doc*_*doc 4 c++ templates const const-correctness

我刚刚发现,当涉及到模板时,这个代码在g ++ 3.4.2中编译,并且除非不调用m(),否则它可以工作:

template <typename T>
class C
{
     T e;

     public:
        C(): e(0) {};

    void m()
    {
        e = 0;
    };
 };
Run Code Online (Sandbox Code Playgroud)

现在可以创建和使用实例

C<const int> c;
Run Code Online (Sandbox Code Playgroud)

直到c.m()没有被称为没有编译错误,但这是合法的吗?

Don*_*eld 11

是的,这是合法的.模板规范是在实例化方法之前,它不存在,因此编译器不会检查它.这是规范中的相关位:

14.7.1 - 隐式实例化

-9-实现不应隐式实例化函数模板,成员模板,非虚拟成员函数,成员类或不需要实例化的类模板的静态数据成员.

  • 该标准表示,如果不能从中生成有效的专业化,则模板格式不正确,但它表示不需要发出诊断信息.但是,在这种情况下,"T"可能是非常量的,因此编译器不能仅为模板发出错误.即使你写"T const c",作为成员,它可以是具有const"operator ="的类类型. (3认同)
  • 大致正确,但更确切地说,它应该谈论一个被实例化而不是被调用的方法.除了调用它之外,获取成员指针也会这样做; 如果一个方法是虚拟的,那么它的实现定义是否延迟实例化. (2认同)
  • 我认为它与SFINAE具有相同的精神 - 它可以让你用模板做事情,如果没有很多防御性的特殊外壳你就无法做到.也就是说,编写不适用于某些模板参数的东西,并且只要不需要工作就无所谓.我会说这是一个例子 - 例如你可能会写一些东西作为一个数组的边界检查迭代器,它也会自然地在一个const数组上工作.非常正确的是,如果用户执行`*it = 0;`(因为`*it`将返回`T&`,其中T为const限定类型),但是之前不会失败. (2认同)