我在C ++中使用以下示例程序
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
namespace mine{
template<class T>
inline void swap(T &a, T &b){
char c= a; //This should not have compiled
a=b;
b=c;
}
}
int main(){
int a,b;
cout<< "Enter two values: ";
cin>>a>>b;
mine::swap(a,b); //type variable T is instantiated as in
cout << a <<' '<<b << endl;
}
我期望编译器在swap函数中抛出一个错误,因为c被声明为char,但是分配了泛型类型变量T的变量。不仅如此,在调用swap时,T被实例化为int。但是,不仅g ++没有给出任何错误,程序也能完美运行。为什么会这样?
答案 0 :(得分:8)
C ++让你有能力用脚射击自己。
事实上,任何整数类型都可以转换为带有实现定义行为的char
。
编译器假设您知道自己在做什么,就是这样。
auto c = a;
这些天是最好的替代品。在C ++ 11之前,你可以编写T C = a;
(当然你仍然可以。)虽然在交换时你应该使用std::move
,但是看看如何实现std::swap
在你的平台上。 (参考How does the standard library implement std::swap?)
-Wconversion
,gcc会警告您。
答案 1 :(得分:0)
首先,将int转换为char是合法的,它是一个缩小的转换,如果您将其配置为编译器,编译器可能会发出警告。
至于代码编译的原因,这是因为类型在编译时是已知的,因此编译器知道对于它初始化的T的所有实例,T可以转换为char。
如果要将a更改为不可转换为char的类型,编译器会抱怨:例如MSVC
以下代码为error C2440: 'initializing' : cannot convert from 'std::string' to 'char'
:
#include "stdafx.h"
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
namespace mine{
template<class T>
inline void swap(T &a, T &b){
char c= a; //This should not have compiled
a=b;
b=c;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
string a("test");
string b("test2");
mine::swap(a,b); //type variable T is instantiated as in
}