为什么VC++编译这段代码,而Clang不会
Why does VC++ compile this code while Clang won't
https://godbolt.org/g/kNlYxl
叮当版本:X86-64 叮当3.9.1
VC++ 版本:x86-64 CL 19 RC
我希望它会编译,因为 const char* 隐式转换为 A,而 A 可转换为 B。有趣的是,clang 声明 const char [5] 不能转换为 A?注意:我现在明白它不是标准行为,但我仍然想知道 VC++ 接受此代码的原因,即是哪种语言扩展导致了它?
叮当声给出的错误:
no viable conversion from 'const char [5]' to 'B'
叮叮当当给出的提示:
note: candidate constructor not viable: no known conversion from 'const char [5]' to 'A' for 1st argument
note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const char [5]' to 'const B &' for 1st argument
#include <string>
#include <vector>
struct A
{
std::string m_test;
A(const char* test)
: m_test(test)
{
}
};
struct B
{
A m_a;
B( A a )
: m_a(a)
{
}
};
int main()
{
B test = "test";
}
只允许一个隐式用户定义的转换,请参阅 [class.conv]/4:
最多一个用户定义的转换(构造函数或转换函数)隐式应用于单个值。
所以它似乎是一个Microsoft C++扩展,事实上,如果你禁用MSVC扩展(/Za
),你会得到同样的错误:
error C2440: 'initializing': cannot convert from 'const char [5]' to 'B'
至于原因 - 它看起来像某种"多次隐式转换"扩展,但在文档中没有提到它。甚至提交了一个错误,它应该被修复,但我想这没有解决。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 整数不会重复超过随机数
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- 如果有换行符,clang 格式不会附加大括号
- Clang不会编译GCC会编译的模板专业化
- 私有运营商删除会触发 GCC 和 Clang 的编译时错误,但不会在 MSVC 上触发编译时错误
- 为什么GCC/Clang甚至在最高优化水平上也不会内联
- Clang在手动链接时不会生成PROFRAW文件
- Clang 在编译时不会计算非 constexpr 变量的 constexpr 函数的值
- 代码调用反向函数不会在Ubuntu 18上的G 或Clang 上编译,但神秘地在Mac OSX上使用
- 为什么VC++编译这段代码,而Clang不会
- 成员函数模板不会在 clang 上编译,但在 GCC 上编译
- Clang-Linux:报告CFI错误而不会崩溃.ftrap功能和-O2
- Visual Studio 和 Clang 不会抛出 std::bad_array_new_length
- Clang 不会在Boost Signals2中构建第一个示例2
- Clang & GCC 在使用智能指针时不会警告非虚拟基析构函数的多态性?
- 此 C++ 模板代码有效吗?G++编译它,但Clang不会
- OS X/Clang 不会使用 c++11 标头
- 多线程代码不会使用 g++ 进行编译,但可以使用 clang++
- 为什么当宏使用 clang 扩展时,"##"不会消失?