Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ MSVC C++;日常生活能力缺陷?_C++_Visual C++_Argument Dependent Lookup - Fatal编程技术网

C++ MSVC C++;日常生活能力缺陷?

C++ MSVC C++;日常生活能力缺陷?,c++,visual-c++,argument-dependent-lookup,C++,Visual C++,Argument Dependent Lookup,这段代码适用于GCC和Clang。当使用自定义类型而不是std::chrono::duration时,它在MSVC中运行良好。在操作符*上使用操作符+时,它可以正常工作。在2018年之前,而不是2017/2015年之前,MSVC可以正常工作 我是否遗漏了任何明显的东西,或者这只是MSVC中的一个bug 为完整起见,以下是来自上述链接的测试用例: #include <chrono> namespace A { class Foo { public: i

这段代码适用于GCC和Clang。当使用自定义类型而不是std::chrono::duration时,它在MSVC中运行良好。在
操作符*
上使用
操作符+
时,它可以正常工作。在2018年之前,而不是2017/2015年之前,MSVC可以正常工作

我是否遗漏了任何明显的东西,或者这只是MSVC中的一个bug

为完整起见,以下是来自上述链接的测试用例:

#include <chrono>

namespace A {
    class Foo {
    public:
        int mCount;
        constexpr explicit Foo(int count) : mCount( count ) {}
    };

    template<class Rep, class Period>
    inline Foo
    operator*(const Foo foo1, const std::chrono::duration<Rep, Period> duration) {
        return Foo(foo1.mCount * duration.count());
    }

    // For testing purposes, this is identical to operator* above.
    template<class Rep, class Period>
    inline Foo
    operator+(const Foo foo1, const std::chrono::duration<Rep, Period> duration) {
        return Foo(foo1.mCount * duration.count());
    }
}

int main() {
    A::Foo foo1(50);

    // This fails to compile for some reason?  Changing the '*' to a '+' works fine however.
    auto foo2 = foo1 * std::chrono::minutes(15);
    return foo2.mCount;
}
#包括
名称空间A{
福班{
公众:
国际计数;
constexpr显式Foo(int count):mCount(count){
};
模板
内联Foo
运算符*(常量Foo foo1,常量std::chrono::duration duration){
返回Foo(foo1.mCount*duration.count());
}
//出于测试目的,这与上面的运算符*相同。
模板
内联Foo
运算符+(常量Foo foo1,常量std::chrono::duration duration){
返回Foo(foo1.mCount*duration.count());
}
}
int main(){
A::富富1(50);
//由于某种原因,无法编译?但是,将“*”更改为“+”可以正常工作。
自动foo2=foo1*std::chrono::minutes(15);
返回foo2.mCount;
}
来自

您观察到的错误是有条件的操作员投诉,SFINAE不知何故并没有“拦截”。如果从Foo的ctor中删除
explicit
,它就会消失

我并不十分熟悉SFINAE行为的细节,但有一点很奇怪:

仅在立即数中的类型和表达式中出现故障 函数类型或其模板参数类型或其 显式说明符(因为C++20)是SFINAE错误。如果评估 替换的类型/表达式会导致副作用,例如 某些模板专门化的实例化,生成 隐式定义的成员函数等,这些副作用中的错误 被视为硬错误

我不确定这是否适用于你的情况。。。如果是这样,那么MS编译器是正确的,但是他们的std库有一个问题。若并没有,那个么这可能是编译器中的一个问题

编辑:显然MS与SFINAE有过一段时间的关系…

来自

您观察到的错误是有条件的操作员投诉,SFINAE不知何故并没有“拦截”。如果从Foo的ctor中删除
explicit
,它就会消失

我并不十分熟悉SFINAE行为的细节,但有一点很奇怪:

仅在立即数中的类型和表达式中出现故障 函数类型或其模板参数类型或其 显式说明符(因为C++20)是SFINAE错误。如果评估 替换的类型/表达式会导致副作用,例如 某些模板专门化的实例化,生成 隐式定义的成员函数等,这些副作用中的错误 被视为硬错误

我不确定这是否适用于你的情况。。。如果是这样,那么MS编译器是正确的,但是他们的std库有一个问题。若并没有,那个么这可能是编译器中的一个问题


编辑:显然MS与SFINAE合作了一段时间…

我已经在向MSVC团队报告了这一情况,他们已经确认这是MSVC中的一个漏洞,并已在MSVC2017的最新版本中修复。谢谢大家的讨论

我已经在向MSVC团队报告了这一点,他们已经确认这是MSVC中的一个bug,并且在MSVC2017的最新版本中已经修复。谢谢大家的讨论

operator+
operator*
之间的区别在于
std::chrono::operator+
需要两个持续时间,因此在这里显然不可行;而
std::chrono::operator*
接受一个持续时间和一个任意类型的参数(可转换为
duration::rep
),并且只能从SFINAE设置的重载中消除。为什么SFINAE在这里失败,我不确定;看起来它应该能工作。
operator+
operator*
之间的区别在于
std::chrono::operator+
需要两个持续时间,因此在这里显然不可行;而
std::chrono::operator*
接受一个持续时间和一个任意类型的参数(可转换为
duration::rep
),并且只能从SFINAE设置的重载中消除。为什么SFINAE在这里失败,我不确定;看起来应该能用。
template<class _Rep1,
    class _Rep2,
    class _Period2> inline
    constexpr typename enable_if<is_convertible<_Rep1,
        typename common_type<_Rep1, _Rep2>::type>::value,
        duration<typename common_type<_Rep1, _Rep2>::type, _Period2> >::type
        operator*(
            const _Rep1& _Left,
            const duration<_Rep2, _Period2>& _Right) ...
    struct common_type  // <Foo, int>
    {   // type is common type of Foo and int for two arguments
        typedef typename decay<
            decltype(false ? declval<Foo>() : declval<int>())
        >::type type;
    };