c – 使用功能模板重载不正常?

前端之家收集整理的这篇文章主要介绍了c – 使用功能模板重载不正常?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我从 http://en.cppreference.com/w/cpp/language/function_template#Function_template_overloading以下的例子
和俚语(3.4)似乎正在处理它,而g(4.8.3)给出了一个“模糊的重载”错误
struct A {};
template<class T> struct B {
  template<class R> void operator*(R&){ cout << "1" << endl; }             // #1
};
template<class T,class R> void operator*(T&,R&) { cout << "2" << endl;}  // #2
int main() {
  A a;
  B<A> b;
  b * a; //prints 1
}

cl声正确地打印1(根据cppreference的预期),而g给出这个错误

test_templates.cpp: In function ‘int main()’:
test_templates.cpp:13:5: error: ambiguous overload for ‘operator*’ (operand types are ‘B<A>’ and ‘A’)
   b * a; //prints 1
     ^
test_templates.cpp:13:5: note: candidates are:
test_templates.cpp:7:26: note: void B<T>::operator*(R&) [with R = A; T = A]
   template<class R> void operator*(R&){ cout << "1" << endl; }            // #1
                          ^
test_templates.cpp:9:33: note: void operator*(T&,R&) [with T = B<A>; R = A]
 template<class T,R&) { cout << "2" << endl;}  // #2

实际上这是不正常的吗?

解决方法

这个例子取自 standard(这是c 11的草案).

14.5.6.2功能模板的部分排序第3段示例:

struct A { };
template<class T> struct B {
  template<class R> int operator*(R&); // #1
};
template<class T,class R> int operator*(T&,R&); // #2
// The declaration of B::operator* is transformed into the equivalent of
// template<class R> int operator*(B<A>&,R&); // #1a
int main() {
  A a;
  B<A> b;
  b * a; // calls #1a
}

所以,这个标准本身就说这是合法的代码.我可以复制粘贴规则,但也可以点击链接跳转到相关的位置.我的观点只是为了证明这是标准定义的正确的可编译代码.

对于我的debian cl ang 3.5.0编译它是值得的,cl ang 3.4.2必须执行-std = c 11,g 4.9.1报告模糊在所有情况下(我甚至尝试了1y).

不过,我很笨拙的行为感到困惑.我以为在早期版本的c中可能是含糊的,消除歧义的规则被添加为c11的一部分,而g没有跟上.但是cl ang 3.5甚至用-std = c 98编译.

猜你在找的C&C++相关文章