【问题标题】:C++ class name injectionC++ 类名注入
【发布时间】:2015-08-02 08:10:07
【问题描述】:

根据标准[class]/2:

... 类名也插入到类本身的范围内;这被称为 injected-class-name....

此外,[basic.scope.pdecl]/9:

injected-class-name(第 9 条)的声明点紧跟在类定义的左大括号之后。

最后,[basic.lookup.classref]/3 及其示例:

如果 unqualified-id 是 ~ type-name,则查找 type-name ...

struct A { };
struct B {
    struct A { };
    void f(::A* a);
};
void B::f(::A* a) {
    a-> ~ A(); // OK: lookup in *a finds the injected-class-name
}

到目前为止,我们可以收集到:

  1. 在 A 类的范围内,存在一个名称 A。
  2. 该名称在类 A 的定义大括号的开头声明。
  3. 该名称命名了一个类型。

如果以上都正确,那么为什么下面的代码编译失败(在MSVC2015中):

struct inj
{};

typedef struct inj::inj inj2;

错误信息

错误 C2039 '{ctor}':不是 'inj' 的成员

似乎与标准不一致:

注意:例如,构造函数在详细类型说明符中不是可接受的查找结果,因此构造函数不会在适当位置使用 注入的类名。 ——尾注

【问题讨论】:

  • 因为它可能不是合法的 c++。
  • 那条笔记出自哪一段?
  • 可能只是另一个 MSVC 错误。 g++ 和 clang++ 都接受这个例子。
  • @sp2danny [class.qual]p2

标签: c++ c++11 language-lawyer


【解决方案1】:

由于以下代码在其他编译器中编译运行正常,是MSVC2015中的一个bug。

#include <boost/type_index.hpp>
#include <iostream>

struct inj
{
    int g;
};

typedef struct inj::inj inj2;

int main()
{

    inj2 ii;
    std::cout << boost::typeindex::type_id_with_cvr<decltype(ii)>().pretty_name() << '\n';
}

更新:Reported as bug

【讨论】:

  • 标准本身 (3.4.3.1) 中有一个几乎相同的代码示例,MSVC 无法编译它,因此最好将其包含在错误报告中。
猜你喜欢
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 2015-11-07
相关资源
最近更新 更多