C++ MSVC C++;日常生活能力缺陷?
这段代码适用于GCC和Clang。当使用自定义类型而不是std::chrono::duration时,它在MSVC中运行良好。在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
操作符*
上使用操作符+
时,它可以正常工作。在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;
};