是通过C++中的typedefs非标准行为来消除歧义的

Is disambiguation via typedefs non-standard behavior in C++?

本文关键字:歧义 非标准 C++ 中的 typedefs      更新时间:2023-10-16

在另一个问题中,在其中一条评论中,我被告知这可能是非标准行为(尤其是向上移动层次结构):

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级没有警告。

我认为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,详细描述的类型说明符似乎包括从属名称,但没有显式允许typedef关键字。这看起来像是2003版标准中的意外遗漏。环境证据:Comeau编译器在没有启用C++0x扩展的严格模式下接受您的代码。

然而,在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.

IIRC,这是一个98标准禁止使用typedef名称的上下文(我手头没有副本),而2011标准似乎允许使用它(语法产品在这里使用类型名称,类型名称的定义允许typedef名称,我没有发现其他文本阻止它在这种情况下使用)。

相关文章: