我不知道为什么下面的代码编译得很好:
#include <iostream>
void bar(int x) {
std::cout << "int " << x << std::endl;
}
void bar(double x) {
std::cout << "double " << x << std::endl;
}
template <typename A, typename B> // Note the order of A and B.
void foo(B x) {
bar((A)x);
}
int main() {
int x = 1;
double y = 2;
foo<int>(x); // Compiles OK.
foo<double>(y); // Compiles OK.
return 0;
}
但是如果我按如下方式切换A
和B
的顺序,那么它将无法编译:
#include <iostream>
void bar(int x) {
std::cout << "int " << x << std::endl;
}
void bar(double x) {
std::cout << "double " << x << std::endl;
}
template <typename B, typename A> // Order of A and B are switched.
void foo(B x) {
bar((A)x);
}
int main() {
int x = 1;
double y = 2;
foo<int>(x); // error: no matching function for call to ‘foo(int&)’
foo<double>(y); // error: no matching function for call to ‘foo(double&)’
return 0;
}
编辑:欢迎临时解释,但如果有人能指出规范所说的确切内容,那就更好了。 谢谢!
在第一个中,编译器知道A
是int
的,因为你用foo<int>
专门告诉它,并且它知道B
也是因为你传递它的参数而int
的。因此,A
和B
都是已知的或可以推断出来的(你可以说:A
被提供,B
是隐含的)。
但是,在第二个中,由于B
排在第一位,A
没有出现在参数列表中,因此编译器无法分辨A
是什么并给出错误。你明确地告诉它foo<int>
B
是什么,然后你传递的参数也是一个B
,在调用时,它是一个与你之前对B
的显式定义一致的int
,但没有隐式或显式地提及A
,所以编译器必须停止并出错。
你真的不需要这个标准,这只是常识。在第二个中,A
到底会是什么?
感谢您提出这个问题,因为我没有意识到您可以在此之前显式指定某些参数并在参数列表中隐式指定其他参数。