c++ - 如果基类是成员函数的参数类型,是否需要指定基类的模板参数?

标签 c++ templates visual-c++ clang standards

以下代码被 VC++ 2013 接受,但被 clang 3.4 拒绝。

哪个编译器符合 C++ 标准?

template<class T>
struct A
{
    T n;
};

template<class T>
struct B : A<T>
{
    // VC++ 2013 : OK
    // clang : error : use of class template 'A' requires template arguments
    B& f1(const A& obj) 
    {
        return *this;
    }

    // VC++ : OK
    // clang : OK
    B& f2(const A<T>& obj)
    {
        return *this;
    }
};

int main()
{
    B<int> b;
}

最佳答案

我的第一直觉是说 VC++ 是正确的。名称查找AB应该找到 injected-class-name A里面 A<T> , 也可以用作 type-name 来引用 A<T> .

C++11 [temp.local]:

1 Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.

2 ...

3 The injected-class-name of a class template or class template specialization can be used either as a template-name or a type-name wherever it is in scope. [ Example:

template <class T> struct Base {
  Base* p;
};

template <class T> struct Derived: public Base<T> {
  typename Derived::Base* p; // meaning Derived::Base<T>
};

然而,与此同时,[temp.dep]§3 指出:

3 In the definition of a class or class template, if a base class depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

基于此,我更倾向于说 clang 实际上是正确的,因为注入(inject)的类名 AA<T> 的范围内, 这取决于 B的模板参数T因此在非限定名称查找期间搜索。支持这一点的次要证据是 [temp.local] 中的示例使用 Derived::Base。而不仅仅是Base .

所以总的来说,我会这么说

  1. 这是一个很好的角落案例,并且

  2. clang 不检查A<T> 的范围其实是对的

关于c++ - 如果基类是成员函数的参数类型,是否需要指定基类的模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24307512/

相关文章:

c++ - 类成员 STL 容器 (const std::array) 的编译时创建,其中填充了元素

html - 如何从 Blogger 的 Breeze 模板中删除作者姓名和图像

c++ - 图像处理基础

visual-studio - 使用 gcc 在 Cygwin 中编译库 (redland) 并使用 Visual Studio (c++) 中的输出

c++ - CMAKE+QT MAC如何设置部署目标?

c++ - 我如何在非模板类中使用模板特化? C++

email - 包含 html 内容的邮件显示换行符或忽略换行符

c++ - 从模板函数返回的特征矩阵改变值

c++ - 使用多重映射算法 (std::minmax_element) 在成对的多重映射中找到最大/最小键 <Class object, enum>?

c++ - 在不使用缓冲区的情况下对 2 个图像进行操作(加法、减法等)