2014-01-28 151 views
3

我最近遇到了问题,我需要一些帮助函数来返回不同类型的实例,类似于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,但我想知道是否和如何有效这是根据标准。两个编译器都支持这个“运气”吗?还是定义名称查找,以确保可以在所有编译器上工作?

+0

您可以使用'Trigger'的构造函数来代替'operator()'超载的'Trigger'对象。 –

+0

@JosephMansfield不幸的是我需要根据参数返回不同的类型,类似于std :: make_pair。 – zennehoy

+0

哦,没有注意到。 –

回答

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 
} 

所以,你的代码是按照标准罚款。 (是否是一种好的风格完全是另一回事!)

1

能够命名结构(或C++中的类)与从C引入的结构的实例类型相同,这是因为结构名称位于单独的名称空间中(而不是C++的namespace虽然)与变量名相比。

相关问题