微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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编译.

原文地址:https://www.jb51.cc/c/114757.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐