【发布时间】:2018-02-08 12:22:57
【问题描述】:
首先,请随意为这个问题提出更好的标题。
考虑以下程序:
#include <numeric>
namespace N { class C {}; }
int operator+( int i, N::C ) { return i+1; }
int main() {
N::C a[10];
std::accumulate( a, a+10, 0 );
}
g++5.4.0:编译成功(见现场演示here)
clang++3.8.0(见现场演示here)
错误:
In file included from source_file.cpp:3:
/usr/include/c++/v1/numeric:75:25: error: invalid operands to binary expression ('int' and 'N::C')
__init = __init + *__first;
~~~~~~ ^ ~~~~~~~~
source_file.cpp:8:11: note: in instantiation of function template specialization 'std::__1::accumulate<N::C *, int>' requested here
std::accumulate( a, a+10, 0 );
^
/usr/include/c++/v1/iterator:640:1: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'N::C'
operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
^
/usr/include/c++/v1/iterator:1044:1: note: candidate template ignored: could not match 'move_iterator<type-parameter-0-0>' against 'N::C'
operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
^
/usr/include/c++/v1/iterator:1400:1: note: candidate template ignored: could not match '__wrap_iter<type-parameter-0-0>' against 'N::C'
operator+(typename __wrap_iter<_Iter>::difference_type __n,
^
1 error generated.
Microsoft Visual C++19.00.23506(见现场演示here)
错误:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\numeric(20): error C2672: 'operator __surrogate_func': no matching overloaded function found
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\numeric(30): note: see reference to function template instantiation '_Ty std::_Accumulate<_Iter,_Ty,_Fn2>(_InIt,_InIt,_Ty,_Fn2)' being compiled
with
[
_Ty=int,
_Iter=N::C *,
_Fn2=std::plus<void>,
_InIt=N::C *
]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\numeric(38): note: see reference to function template instantiation '_Ty std::accumulate<_InIt,_Ty,std::plus<void>>(_InIt,_InIt,_Ty,_Fn2)' being compiled
with
[
_Ty=int,
_InIt=N::C *,
_Fn2=std::plus<void>
]
source_file.cpp(8): note: see reference to function template instantiation '_Ty std::accumulate<N::C*,int>(_InIt,_InIt,_Ty)' being compiled
with
[
_Ty=int,
_InIt=N::C *
]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\numeric(20): error C2893: Failed to specialize function template 'unknown-type std::plus<void>::operator ()(_Ty1 &&,_Ty2 &&) const'
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\numeric(20): note: With the following template arguments:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\numeric(20): note: '_Ty1=int &'
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\numeric(20): note: '_Ty2=N::C &'
Error(s):
In file included from source_file.cpp:3:
/usr/include/c++/v1/numeric:75:25: error: invalid operands to binary expression ('int' and 'N::C')
__init = __init + *__first;
~~~~~~ ^ ~~~~~~~~
source_file.cpp:8:11: note: in instantiation of function template specialization 'std::__1::accumulate<N::C *, int>' requested here
std::accumulate( a, a+10, 0 );
^
/usr/include/c++/v1/iterator:640:1: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'N::C'
operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
^
/usr/include/c++/v1/iterator:1044:1: note: candidate template ignored: could not match 'move_iterator<type-parameter-0-0>' against 'N::C'
operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
^
/usr/include/c++/v1/iterator:1400:1: note: candidate template ignored: could not match '__wrap_iter<type-parameter-0-0>' against 'N::C'
operator+(typename __wrap_iter<_Iter>::difference_type __n,
^
1 error generated.
这个程序在英特尔 C++ 编译器上编译也没有任何错误。
那么,问题是这里有哪些编译器?这段代码格式不正确吗?标准对此有何规定?
【问题讨论】:
-
是的,如果我输入
operator+ intonamespace N`,它就可以在 clang 上运行` -
众所周知,Visual Studio 编译器不实现两阶段查找(但它应该实现)。
-
投反对票的人愿意解释为什么你投反对票的原因?
-
@JesperJuhl:但我没有在我的代码中使用用户定义的函数模板,那么如何在这里应用 2 阶段名称查找?
标签: c++ operator-overloading language-lawyer overload-resolution name-lookup