相同的类和实例名称

时间:2014-01-28 09:43:16

标签: c++

我最近遇到的问题是我需要一些辅助函数来返回不同类型的实例,类似于std::make_pair。我选择的语法是:

Event event(Trigger(...), []() { });

其中...是一个基于...类型创建不同触发类型的简单参数(例如TimeUserInput等。)

此外,我想要一些可以直接使用的预定义触发器,例如:

Event event(Trigger::OnInit, []() { });

我发现定义一个名为Trigger的类和实例允许我支持这两种语法:

static const struct Trigger {
    static const OnceTrigger OnInit;

    TimeTrigger operator()(Time const &) const;
    UserTrigger operator()(UserInput const &) const;
} Trigger;

注意名称相同的类型和实例名称。

这适用于GCC和MSVC,但我想知道根据标准是否以及如何有效。两个编译器都支持这个“运气”吗?或者是否定义了名称查找,以确保它可以在所有编译器上运行?

2 个答案:

答案 0 :(得分:1)

能够命名一个结构(或C ++中的类)类型与该结构的实例相同是从C引入的,这是因为结构名称在一个单独的命名空间中(不是C ++ {{ 1}}虽然)与变量名相比。

答案 1 :(得分:1)

在函数调用语法Trigger(...)中,类按实例3.3.10隐藏:

  

2 - 类名(9.1)或枚举名(7.2)可以通过在同一范围内声明的变量,数据成员,函数或枚举器的名称隐藏。如果类或枚举名称和变量,数据成员,函数或枚举器在同一作用域(按任何顺序)中声明具有相同名称,则类或枚举名称将隐藏在变量,数据成员,函数或枚举器名称可见。

在限定名称查找语法Trigger::OnInit中,该类按3.4.3可见:

  

1 - [...]查找[{] ::之前的名称仅考虑其专业化类型的名称空间,类型和模板。

实际上,该标准有一个示例,它演示了限定名称查找如何不隐藏类型名称:

class A {
public:
  static int n;
};
int main() {
  int A;
  A::n = 42; // OK
  A b; // ill-formed: A does not name a type
}

所以你的代码符合标准。 (它是否是一种好的风格完全是另一回事!)