当前位置:  开发笔记 > 编程语言 > 正文

转换在Visual Studio 2015中不明确,但与clang不同

如何解决《转换在VisualStudio2015中不明确,但与clang不同》经验,为你挑选了2个好方法。

以下代码是googlemock项目中的代码的简化版本,无法在Visual Studio 2015 Update 1中编译,但它在clang [Apple LLVM版本7.0.0(clang-700.1.76)]上编译.

struct ConvertibleFromAny
{
    ConvertibleFromAny(int a_value);

    template 
    ConvertibleFromAny(const T& a_value);
};

template 
struct Matcher
{
    Matcher(T value);
};

template 
struct EqMatcher
{
    explicit EqMatcher(const Rhs& rhs);

    template 
    operator Matcher() const;
};

int main()
{
    EqMatcher em(1);
    Matcher m = em;

    return 0;
}

错误发生在 分配 声明

Matcher m = em;

并且错误消息是

error C2440: 'initializing': cannot convert from 'EqMatcher' to 'Matcher'
note: No constructor could take the source type, or constructor overload resolution was ambiguous

我可以天真地看到成员电话之间的歧义

EqMatcher::operator Matcher()

和概念上类似的初始化

Matcher m(ConvertibleFromAny>(em))

我的猜测是clang排除了第二种选择.

编辑:受TC的评论启发,我测试了以下内容:

struct A
{
};

struct X
{
    X(const A&);
};

struct B
{
    B(const X&);
};

int main()
{
    A a;

    B b = a;
}

它与VS 2015编译,但不与clang编译.我无法找到任何文档,即Visual C++实现在这方面有意偏离标准.

这是一个众所周知的问题吗?



1> melak47..:

如果我启用"禁用语言扩展"(/Za)标志,那么您的代码示例都会使用VS2015 Update 1生成预期结果.也就是说,第一个编译,第二个编译不编译.

不过,我不确定哪个扩展特别干扰.我找到了这个MSDN页面:C和C++的Microsoft Extensions,但它似乎并不完整 - 例如,没有提到将非const T&绑定到rvalue.



2> eh9..:

我无法找到任何文档,即Visual C++实现在这方面有意偏离标准.

在这里:编译器警告(级别1)C4928.信息是

非法复制初始化; 隐式应用了多个用户定义的转换

这样说:

编译器在所有这些例程中执行了代码.

所以有一个事实上的语言扩展,微软几乎没有记录.

您可以使用命令行参数/we4928将警告转换为错误,从而有效地删除此单个扩展.请参阅此处了解这些参数.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有