我正在学习C ++,并且遇到了我想了解更多的知识。
假设我尝试将数组声明为:
int myarray[] = {1, 2, 3, 4.1};
请注意索引3处的非整数4.1。在Visual Studio中,这将带有警告,但在gcc中它将无法编译。当为数组的元素分配错误的类型时,标准(11、14或17)是否有关于自动转换的说法,还是由编译器决定会发生什么(或其他事情)?我想弄清楚为什么结果不同。
答案 0 :(得分:2)
C++11
之前的代码是合法的。由于C++11
被认为是狭窄的转换(从double
到int
,因此会丢失信息)并且是非法的。
您使用什么编译器和哪个版本的编译器很重要。 Visual Studio,尤其是稍旧的版本实际上并没有完全实现任何标准。它们实现C++11
位,C++14
位,C++17
位。有了可能会更改的最新版本,最近我还没有关注它的发展。
gcc的较旧版本默认为gnu++98
,它是带有gnu扩展名的C++98
,而较新的版本默认为gnu ++ 11和gnu ++ 14。出于好奇,如果您想查看它是否可以在gcc中使用,请使用-std=c++98
,并且只会收到警告。
事后看来,我们已经知道,允许可能丢失信息的隐式转换(例如,从浮点到整数,从long long
到int
)并不是一个好主意。对于C++11
,已考虑到这一点。将所有此类隐式转换视为非法,被认为是一个重大突破。列表初始化的引入提供了中间立场:不允许仅在列表初始化中缩小转换范围,并建议使用列表初始化作为初始化对象的实际方法。不利之处在于,这是数组初始化的一项重大突破,但其好处被认为具有更大的价值。
int a = 2.4; // still allowed, but not recommended
int a(2.4); // still allowed, but not recommended
int a = {2.4}; // New way to initialize. Narrowing conversion, illegal
int a{2.4}; // New and recommended way to initialize. Narrowing conversion, illegal
您可以在此处详细了解狭义转化:https://en.cppreference.com/w/cpp/language/list_initialization