结合“使用”部分重载的指令:gcc 功能还是 intel 错误?

发布于 2024-12-07 23:00:45 字数 1979 浏览 4 评论 0原文

我希望将一组用 C++ 编写的库与英特尔编译器一起使用。我已附上演示该问题的示例代码。库中有很多地方将“using”指令与部分重载结合起来(例如,我想使用基类中的 foo(void) 方法,但在派生类中重新实现第二个版本 fo foo ) 。 gcc 没有问题,但 intel 有问题。

#include <iostream>
template <class F>
struct Interface
  {
     static const F f=10;
  };

template <class F>
struct Base : public Interface<F>
  {
     void foo (void) { std::cout << "void" << std::endl; }
     template <class FF>
     void foo (Interface<FF> &ii) { std::cout << "F : " << ii.f << std::endl; }
  };

template <class F,int i>
struct Derived : public Base<F>
  {
    // void foo (void) { Base<F>::foo(); }  // works fine
    using Base<F>::foo;                     // gives error
    template <class FF>
    void foo (Interface<FF> &ii) { std::cout << "Derived<" << i << "> F : " << ii.f << std::endl; }
 };

int main (void)
  {
    Derived<double,10> o;
    o.foo();                  // ok
    o.foo (o);                // problem
  }

icc 给出的编译器错误是:

test.cc(30): error: more than one instance of overloaded function "Derived<F, i>::foo    [with F=double, i=10]" matches the argument list:
        function template "void Base<F>::foo(Interface<FF> &) [with F=double]"
        function template "void Derived<F, i>::foo(Interface<FF> &) [with F=double, i=10]"
        argument types are: (Derived<double, 10>)
        object type is: Derived<double, 10>
o.foo (o);                // problem
  ^

compilation aborted for test.cc (code 2)

如果删除该行

using Base<F>::foo;

并将其替换为该行,

void foo (void) { Base<F>::foo(); }

则一切正常。

我的问题是有谁知道这是一个特殊的 gcc 功能还是 icc 错误?或者是否有另一种不涉及更改代码的解决方法?

这是使用 g++.real (Ubuntu 4.4.3-4ubuntu5) 4.4.3 和 icc (ICC) 12.0.2 20110112。

I wish to use a set of libraries written in C++ with the Intel compilers. I've attached sample code which demonstrates the problem. There are many places in the libraries where they make use of combining the 'using' directive with partial overloading (e.g., I want to use the foo(void) method from the base class but reimplement the second version fo foo in the derived class). gcc does not have a problem but intel does.

#include <iostream>
template <class F>
struct Interface
  {
     static const F f=10;
  };

template <class F>
struct Base : public Interface<F>
  {
     void foo (void) { std::cout << "void" << std::endl; }
     template <class FF>
     void foo (Interface<FF> &ii) { std::cout << "F : " << ii.f << std::endl; }
  };

template <class F,int i>
struct Derived : public Base<F>
  {
    // void foo (void) { Base<F>::foo(); }  // works fine
    using Base<F>::foo;                     // gives error
    template <class FF>
    void foo (Interface<FF> &ii) { std::cout << "Derived<" << i << "> F : " << ii.f << std::endl; }
 };

int main (void)
  {
    Derived<double,10> o;
    o.foo();                  // ok
    o.foo (o);                // problem
  }

The compiler error that icc gives is:

test.cc(30): error: more than one instance of overloaded function "Derived<F, i>::foo    [with F=double, i=10]" matches the argument list:
        function template "void Base<F>::foo(Interface<FF> &) [with F=double]"
        function template "void Derived<F, i>::foo(Interface<FF> &) [with F=double, i=10]"
        argument types are: (Derived<double, 10>)
        object type is: Derived<double, 10>
o.foo (o);                // problem
  ^

compilation aborted for test.cc (code 2)

If you remove the line

using Base<F>::foo;

and replace it with the line

void foo (void) { Base<F>::foo(); }

everything works fine.

My question is does anyone know if this is a special gcc feature or icc bug? Or is there another work around which would not involve changing the code?

This is with g++.real (Ubuntu 4.4.3-4ubuntu5) 4.4.3 and icc (ICC) 12.0.2 20110112.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌︼了一个春 2024-12-14 23:00:45

对于 C++11,相关标准引用可以在

7.3.3 using 声明 [namespace.udecl]

14/ 如果命名空间作用域或块作用域中的函数声明与 using 声明引入的函数具有相同的名称和相同的参数类型,并且这些声明没有声明相同的函数,该程序格式错误。

这支持基于 EDG 的编译器。然而,有一种特殊情况是在类中使用的:

15/ 当 using 声明将名称从基类引入派生类作用域时,派生类中的成员函数和成员函数模板将覆盖和/或隐藏成员函数和成员函数模板在基类中具有相同的名称、parameter-type-list (8.3.5)、cv-qualification 和 ref-qualifier(如果有)(而不是冲突)。 [ 注意:有关命名构造函数的 using 声明,请参阅 12.9。 -结尾
注意] [示例:

struct B {
  virtual void f(int);
  virtual void f(char);
  void g(int);
  void h(int);
};

struct D : B {
  using B::f;
  void f(int); // OK: D::f(int) overrides B::f(int);

  using B::g;
  void g(char); // OK

  using B::h;
  void h(int); // OK: D::h(int) hides B::h(int)
};

void k(D* p)
{
  p->f(1); // calls D::f(int)
  p->f(’a’); // calls B::f(char)
  p->g(1); // calls B::g(int)
  p->g(’a’); // calls D::g(char)
}

—结束示例]

因此,在 C++11 中,Comeau 和 Intel 似乎是错误的。我不知道这些规则是否同样适用于C++03

For C++11, the relevant Standard quote can be found in

7.3.3 The using declaration [namespace.udecl]

14/ If a function declaration in namespace scope or block scope has the same name and the same parameter types as a function introduced by a using-declaration, and the declarations do not declare the same function, the program is ill-formed.

This supports the EDG-based compilers. However, a special case is meant for use in classes:

15/ When a using-declaration brings names from a base class into a derived class scope, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting). [ Note: For using-declarations that name a constructor, see 12.9. —end
note ] [ Example:

struct B {
  virtual void f(int);
  virtual void f(char);
  void g(int);
  void h(int);
};

struct D : B {
  using B::f;
  void f(int); // OK: D::f(int) overrides B::f(int);

  using B::g;
  void g(char); // OK

  using B::h;
  void h(int); // OK: D::h(int) hides B::h(int)
};

void k(D* p)
{
  p->f(1); // calls D::f(int)
  p->f(’a’); // calls B::f(char)
  p->g(1); // calls B::g(int)
  p->g(’a’); // calls D::g(char)
}

—end example ]

Therefore, in C++11, it seems Comeau and Intel are wrong. I do not know whether these rules equally applied in C++03

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文