void func(int) {} template<typename T> void templatedFunc(T) {} int main() { void (*p)(int) = func; bool test1 = p==func; //bool test2 = p==templatedFunc<int>; // compilation error bool test3 = p==&templatedFunc<int>; // but this works }
如果您取消对test2行的注释,并尝试使用g编译代码,则会收到以下错误:
test.cpp: In function ‘int main()’: test.cpp:8:21: error: assuming cast to type ‘void (*)(int)’ from overloaded function [-fpermissive] bool test2 = p==templatedFunc<int>; // compilation error ^~~~~~~~~~~~~~~~~~
我得到这个结果在g 5.3.0和6.2.0.同时,编译与cl 3.6.0成功,没有警告.
哪个编译器根据标准这里是正确的,这给出错误或cl,哪些不?
解决方法
A use of an overloaded function name without arguments is resolved in certain contexts to a function,a
pointer to function or a pointer to member function for a specific function from the overload set. A function
template name is considered to name a set of overloaded functions in such contexts. The function selected
is the one whose type is identical to the function type of the target type required in the context. [ Note:
That is,the class of which the function is a member is ignored when matching a pointer-to-member-function
type. — end note ] The target can be:(1.1) — an object or reference being initialized (8.5,8.5.3,8.5.4),
(1.2) — the left side of an assignment (5.18),
(1.3) — a parameter of a function (5.2.2),
(1.4) — a parameter of a user-defined operator (13.5),
(1.5) — the return value of a function,operator function,or conversion (6.6.3),
(1.6) — an explicit type conversion (5.2.3,5.2.9,5.4),or
(1.7) — a non-type template-parameter (14.3.2).
The overloaded function name can be preceded by the & operator. An overloaded function name shall not
be used without arguments in contexts other than those listed. [ Note: Any redundant set of parentheses
surrounding the overloaded function name is ignored (5.1). — end note ]
你看到从(1.1)到(1.7)的列表中缺少什么…内置的运算符!
如果你声明一个operator ==的重载,那么gcc不会抱怨比较,比你不必明确地专门化模板函数:
void func(int) {} template<class T> void templatedFunc(T) {} struct s{}; bool operator==(s,void(*)(int)){return false;} int main() { void (*p)(int) = templatedFunc; bool test1 = p==func; bool test2 = s{} == templatedFunc<int>; // no error - no overload resolution bool test3 = s{} == templatedFunc; // no error - overload resolution bool test4 = p == templatedFunc<int>; // gcc error,but not an error - // no overload resolution //bool test5 = p == templatedFunc; // error - overload resolution not // performed for built-int operators }
test2和test3使用gcc进行编译. test4没有在gcc上编译,但是没有重载解析,你明确专门的功能.真的应该编译test5不按照标准进行编译.在这种情况下,gcc会产生与test4完全相同的错误信息.这肯定是一个gcc错误.