Tom*_*m R 7 c++ compiler-construction gcc overloading icc
我希望使用一组用C++编写的库和英特尔编译器.我附上了演示问题的示例代码.库中有很多地方使用'using'指令和部分重载(例如,我想从基类中使用foo(void)方法,但在派生类中重新实现第二个版本fo foo) .gcc没有问题,但英特尔确实如此.
#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
}
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
如果删除该行
using Base<F>::foo;
Run Code Online (Sandbox Code Playgroud)
并用线替换它
void foo (void) { Base<F>::foo(); }
Run Code Online (Sandbox Code Playgroud)
一切正常.
我的问题是有人知道这是一个特殊的gcc功能还是icc bug?或者是否还有其他工作不涉及更改代码?
这是用g ++.real(Ubuntu 4.4.3-4ubuntu5)4.4.3和icc(ICC)12.0.2 20110112.
对于C++ 11,可以在中找到相关的标准引用
7.3.3使用声明[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)
}
Run Code Online (Sandbox Code Playgroud)
- 末端的例子]
因此,在C++ 11中,似乎是Comeau和Intel都错了.我不知道这些规则是否同样适用于C++ 03