为什么编译器没有给出错误?

时间:2017-11-16 14:22:16

标签: c++

我在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 ++没有给出任何错误,程序也能完美运行。为什么会这样?

2 个答案:

答案 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
}