#include <stdio.h>
#include <type_traits>
template<typename S, typename T>
int foo(typename T::type s) {
return 1;
}
template<typename S, typename T>
int foo(S s) {
return 2;
}
int main(int argc, char* argv[]) {
int x = 3;
printf("%d\n", foo<int, std::enable_if<true, int>>(x));
return 0;
}
输出:
1
为什么不给这个编译错误?当生成模板代码时,函数int foo(typename T::type search)
和int foo(S& search)
是否具有相同的签名?
如果更改模板函数签名一点点,它仍然有效(因为我希望给上面的例子):
template<typename S, typename T>
void foo(typename T::type s) {
printf("a\n");
}
template<typename S, typename T>
void foo(S s) {
printf("b\n");
}
但这并不,但唯一的区别是一个具有一个int签名,另一个由第一个模板参数定义。
template<typename S, typename T>
void foo(typename T::type s) {
printf("a\n");
}
template<typename S, typename T>
void foo(int s) {
printf("b\n");
}
编译器错误(锵):
test.cpp:26:2: error: call to 'foo' is ambiguous
foo<std::enable_if<true, int>>(3);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:16:6: note: candidate function [with T = std::__1::enable_if<true, int>]
void foo(typename T::type s) {
^
test.cpp:21:6: note: candidate function [with T = std::__1::enable_if<true, int>]
void foo(int s) {
^
1 error generated.
我用下面的代码来为一个项目我的工作,我很害怕,有一个微妙的语言,我我不理解这会在某些情况下导致一些未定义的行为。我还应该提到它在Clang和VS11上编译,所以我不认为这只是一个编译器错误。
编辑:校正的第二种情况(拼写错误);添加了来自Clang的错误消息。
编辑#2:对于那些询问T :: type是什么意思的人。
http://en.cppreference.com/w/cpp/types/enable_if来自:
模板<布尔B,类T =空隙> 结构enable_if;
如果B是真实的,性病:: enable_if有一个公共的typedef构件类型,等于 至T;否则,没有成员typedef。
enable_if是一个结构。基本上,如果在enable_if的第一个模板参数中评估的表达式为真(并且在上面的示例中,则是),那么将会有一个公共成员type
,它具有与第二个模板参数相同的类型。
在enable_if<true, int>
的情况下,enable_if ::类型具有int类型。
这不奇怪,你最后一个案例不编译。当函数仅接收一个函数时,您正在使用两个模板参数。 –
谢谢,我想我在那里复制了错误的案例。固定。 – vmrob
我是C++ noob,所以不要苛刻我......第一个例子不工作,因为你重写第一个方法吗?我很想知道这个答案。我打算明年学习C++。 –