#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 bug?或者是否有其他工作不涉及更改代码?
这与g .real(Ubuntu 4.4.3-4ubuntu5)4.4.3和icc(ICC)12.0.2 20110112有关.
解决方法
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.
这支持基于EDG的编译器.但是,特殊情况适用于类:
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 ]
因此,在C 11中,似乎Comeau和Intel都是错的.我不知道这些规则是否同样适用于C 03