当默认参数是初始值设定项列表时,它调用的构造函数似乎Visual Studio
只是被破坏了。这段代码:
#include <iostream>
struct test {
test () { std::cout << "test ()" << std::endl ; }
test (int) { std::cout << "test (int)" << std::endl ; }
};
void func( test const &s = {} )
{
}
int main()
{
test s = {} ;
func() ;
}
gcc
在and中产生这个结果,在这里clang
看到它:
test ()
test ()
而Visual Studio
产生这个结果:
test ()
test (int)
对于这段代码:
#include <iostream>
#include <initializer_list>
struct test {
test () { std::cout << "test ()" << std::endl ; };
test (int) { std::cout << "test (int)" << std::endl ; };
test ( std::initializer_list<int>) { std::cout << "test (initializer_list<int>)" << std::endl ; } ;
};
void func( test const &s = {0} )
{
}
int main()
{
test s = {0} ;
func() ;
}
gcc
并clang
产生这个结果在这里看到它:
test (initializer_list<int>)
test (initializer_list<int>)
而Visual Studio
产生此错误:
error C2440: 'default argument' : cannot convert from 'initializer-list' to 'const test &'
Reason: cannot convert from 'initializer-list' to 'const test'
No constructor could take the source type, or constructor overload resolution was ambiguous
更新
为了进行完整性检查,我回到了标准,以确保这种差异的根源没有一些奇怪的规则,或者可能是一些使这段代码格式错误的限制。据我所知,这段代码不是格式错误的。节8.3.5
语法特别允许这样做:
parameter-declaration:
attribute-specifier-seqopt decl-specifier-seq declarator
attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
[...]
似乎8.5
初始化程序或8.3.6
默认参数部分没有添加任何限制,但此缺陷报告994.braced-init-list 作为默认参数和工作文件将大括号初始化器作为默认参数的措辞清楚地表明它是有意的并概述了更改符合标准以允许它并查看增量没有明显的限制。