MSVC运算符错误| 我正在研究一个广泛使用C++模板的库。在编写代码时,我遇到了这样的情况(当然是简化的): #包括 名称空间ns{ 模板 c类{}; a类{}; 模板 b类{ 公众: 模板 汽车 取(A,B){ 返回c{}; } }; 模板 汽车 make_b(A){ 返回b{}; } 模板 汽车 操作员|(A | A,B | B){ 返回_b.获取(_a,_b); } } 使用名称空间ns; int main(){ a{}make|b(a{}); 返回0; }

MSVC运算符错误| 我正在研究一个广泛使用C++模板的库。在编写代码时,我遇到了这样的情况(当然是简化的): #包括 名称空间ns{ 模板 c类{}; a类{}; 模板 b类{ 公众: 模板 汽车 取(A,B){ 返回c{}; } }; 模板 汽车 make_b(A){ 返回b{}; } 模板 汽车 操作员|(A | A,B | B){ 返回_b.获取(_a,_b); } } 使用名称空间ns; int main(){ a{}make|b(a{}); 返回0; },c++,templates,visual-c++,C++,Templates,Visual C++,在使用msvc 19(Visual Studio 2017)编译时,我遇到以下错误: /opt/编译器资源管理器/Windows /19.1025017/LIB/NET/INORK/XLARALE(314):警告C430:C++异常处理程序,但未启用展开语义。指定/EHsc (28):错误C2228:“.take”的左侧必须具有类/结构/联合 (28):注:类型为“ /opt/compiler explorer/windows/19.10.25017/lib/native/include/xst

在使用msvc 19(Visual Studio 2017)编译时,我遇到以下错误:

/opt/编译器资源管理器/Windows /19.1025017/LIB/NET/INORK/XLARALE(314):警告C430:C++异常处理程序,但未启用展开语义。指定/EHsc (28):错误C2228:“.take”的左侧必须具有类/结构/联合 (28):注:类型为“

/opt/compiler explorer/windows/19.10.25017/lib/native/include/xstring(2923):注意:请参阅正在编译的函数模板实例化“auto-ns::operator |(A,B)”的参考 具有 [ A=无符号整数, B= ] /opt/compiler explorer/windows/19.10.25017/lib/native/include/xstring(2922):注意:编译类模板成员函数“void std::basic_string,std::allocator>::shrink_to_fit(void)”时

/opt/compiler explorer/windows/19.10.25017/lib/native/include/system_error(658):注意:请参阅正在编译的函数模板实例化“void std::basic_string,std::allocator>::shrink_to_fit(void)”

/opt/compiler explorer/windows/19.10.25017/lib/native/include/stdexcept(22):注意:请参阅正在编译的类模板实例化“std::basic_string,std::allocator>”的参考

使用名称空间删除
是可行的,但我不想禁止它(为什么我应该?)。有解决办法吗

编辑:当然,我用GCC和Clang测试了代码-从4.9和clang3在GCC下编译,所以这完全是MSVC的问题


EDIT2:我查看了报告的错误,当使用
名称空间时,MSVC似乎在扩展其标准库中重载的
运算符|
的范围。它是这样工作的,但我无法解释为什么它不能以原来的方式工作,希望它能帮助其他人

虽然我的猜测是,您的模板太宽了,它被std库中的一些代码所暗示。实际上,如果您只需注释掉任何std头或使用命名空间ns删除
,代码也可以工作

namespace ns {
    template<class A, class B>
    class c {};

    class a {};

    template<class A>
    class b {
    public:
        using MyA = A;
        template<class B>
        auto
            take(A, B) {
            return c<A, B>{};
        }
    };

    template<class A>
    auto
        make_b(A) {
        return b<A>{};
    }

    template<class B>
    auto
        operator|(typename B::MyA _a, B _b) {
        return _b.take(_a, _b);
    }
}
ns{
模板
c类{};
a类{};
模板
b类{
公众:
使用MyA=A;
模板
汽车
拿(A,B){
返回c{};
}
};
模板
汽车
make_b(A){
返回b{};
}
模板
汽车
运算符|(类型名B::MyA a,B B){
返回_b.获取(_a,_b);
}
}

A)如果它没有编译,也许你不是在问优化问题?B) 也许你想发布实际的错误消息?对不起,编辑后的评论,`couse犯了一个错误。只需在
godbolt
上查看你的代码,你就错过了第一条错误消息,请将其包含在你的帖子中。我必须说这非常有趣。您刚刚使用MyA=A添加了这个
?@bartop是的,就是这样,我猜模板不是太宽,因为gcc和clang接受它。更像是msvc在它的库中做了一些肮脏的事情,假设没有人会做我做过的事情。
namespace ns {
    template<class A, class B>
    class c {};

    class a {};

    template<class A>
    class b {
    public:
        using MyA = A;
        template<class B>
        auto
            take(A, B) {
            return c<A, B>{};
        }
    };

    template<class A>
    auto
        make_b(A) {
        return b<A>{};
    }

    template<class B>
    auto
        operator|(typename B::MyA _a, B _b) {
        return _b.take(_a, _b);
    }
}