在C ++中通过typedef非标准行为消除歧义吗?

时间:2012-01-24 15:37:13

标签: c++ standards

In another question,在其中一条评论中,我被告知此可能是非标准行为(尤其是向上移动层次结构):

struct f1
{
  int operator() (int a, int b) const { return a + b; }
};

struct f2
{
  int operator() (int a, int b) const { return a * b; }
};

struct f3 : f2
{
  typedef f2  base_type;
  int operator() (int a, int b) const 
  { return base_type::operator()(a,b) * (a / b); }
};

struct f4
{
  int operator() (int a, int b) const { return a - b; }
};

struct f5 : f4
{
  typedef f4  base_type; 
  int operator() (int a, int b) const 
  { return base_type::operator()(a,b) * a * b; }
};

template <typename F1, typename F3, typename F5>
class foo : F1, F3, F5 
{
  typedef F1    base_type_1;
  typedef F3    base_type_3;
  typedef F5    base_type_5;

public:
  int f1(int a, int b) { return base_type_1()(a, b); }
  int f3(int a, int b) { return base_type_3()(a, b); }
  int f5(int a, int b) { return base_type_5()(a, b); }

  int f3f2(int a, int b) 
  { 
    return base_type_3::base_type::operator()(a, b) * 
           base_type_3::operator()(a, b);
  }

  int f5f4(int a, int b)
  { 
    return base_type_5::base_type::operator()(a, b) * 
           base_type_5::operator()(a, b);
  }
};

int main()
{
  foo<f1, f3, f5> f;
  f.f1(1,2);
  f.f3(1,4);
  f.f5(1,5);

  f.f3f2(1, 1);
  f.f5f4(2, 2);

  return 0;
}

编辑:这是在VC ++ 2008下编译的,在第4级没有警告。

2 个答案:

答案 0 :(得分:2)

我认为ISO / IEC 14882:2003中的案例并不清楚。虽然它说:

3.4.31/1 Qualified name lookup
...
If the name found is not a class-name (clause 9) or namespace-name (7.3.1),
the program is ill-formed.

还有一个关于什么构成类名的未决问题:

9 Classes
Class-specifiers and elaborated-type-specifiers (7.1.5.3) are used to make class-names.

...如果查阅7.1.5.3, elaborated-type-specifiers 似乎包含依赖名称,但没有明确允许typedef关键字。它似乎就像标准版本2003中的意外遗漏一样。环境证据:在没有启用C ++ 0x扩展的严格模式下,Comeau Compiler接受您的代码。

但是,这种方式使用依赖名称在ISO / IEC 14882:2011中明确有效。这是相关的措辞:

3.4.3/1 Qualified name lookup
...
If a :: scope resolution operator in a nested-name-specifier is not preceded
by a decltype-specifier, lookup of the name preceding that :: considers only 
namespaces, types, and templates whose specializations are types.
If the name found does not designate a namespace or a class, enumeration, or
dependent type, the program is ill-formed.

答案 1 :(得分:0)

IIRC,这是98标准阻止使用typedef-name(我没有我的副本方便检查)的上下文,而2011标准似乎允许它(语法生成在这里使用类型名称和type-name的定义允许使用typedef-name,我没有找到阻止在这种情况下使用它的附加文本。)