[英]MSVC C++ ADL bug?
This code works fine with GCC and Clang. 这段代码可以在GCC和Clang上正常工作。 It works fine in MSVC when using a custom type instead of std::chrono::duration.
当使用自定义类型而不是std :: chrono :: duration时,它在MSVC中工作正常。 It works fine when using an
operator+
over operator*
. 当使用
operator+
over operator*
时,它可以正常工作。 It works fine with MSVC pre 2018 instead of 2017/2015. 它可以在2018年之前的MSVC而不是2017/2015之前正常工作。
Am I missing anything obvious, or is this just a bug in MSVC? 我是否遗漏了任何明显的内容,或者这仅仅是MSVC中的错误? https://godbolt.org/z/EUWV7e
https://godbolt.org/z/EUWV7e
For completeness, here is the test case from the above link: 为了完整起见,以下是上述链接中的测试用例:
#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;
}
from <chrono>
: 来自
<chrono>
:
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) ...
Note that since std::chrono::minutes
is duration<int, ratio<60>>
-- _Rep2
is int
. 请注意,由于
std::chrono::minutes
是duration<int, ratio<60>>
_Rep2
是int
。 Now common_type<_Rep1, _Rep2>
expands to (see <type_traits>
): 现在
common_type<_Rep1, _Rep2>
扩展为(请参见<type_traits>
):
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;
};
Error you observe is conditional operator complaint that somehow isn't "intercepted" by SFINAE. 您观察到的错误是有条件的操作员投诉,表明SFINAE并未“拦截”。 If you remove
explicit
from Foo's ctor -- it'll go away. 如果从Foo的ctor中删除
explicit
,它将消失。
I am not intimately familiar with finer points of SFINAE behavior, but cppreference.com has curious note: 我对SFINAE行为的细节并不十分熟悉,但是cppreference.com有一个奇怪的提示:
Only the failures in the types and expressions in the immediate context of the function type or its template parameter types or its explicit specifier (since C++20) are SFINAE errors.
只有函数类型或其模板参数类型或其显式说明符(自C ++ 20起)的直接上下文中的类型和表达式失败才是SFINAE错误。 If the evaluation of a substituted type/expression causes a side-effect such as instantiation of some template specialization, generation of an implicitly-defined member function, etc, errors in those side-effects are treated as hard errors.
如果对替换类型/表达式的求值引起副作用,例如某些模板专门化的实例化,隐式定义的成员函数的生成等,则将这些副作用中的错误视为硬错误。
I am not sure this applies to your case... If it does -- then MS compiler is right, but their std lib has a problem. 我不确定这是否适用于您的情况...如果确实如此-那么MS编译器是正确的,但是其std lib有问题。 If it doesn't -- then it is probably an issue in compiler.
如果不是,则可能是编译器中的一个问题。
Edit: apparently MS had problems with SFINAE for a while... 编辑:显然MS有一段时间SFINAE 问题 ...
I've reported this to the MSVC team at https://developercommunity.visualstudio.com/content/problem/381899/adl-sfinae-bug-in-mvc20152017-when-using-stdchrono.html and they've confirmed it is a bug in MSVC, and has been fixed in the latest release of MSVC2017. 我已在https://developercommunity.visualstudio.com/content/problem/381899/adl-sfinae-bug-in-mvc20152017-when-using-stdchrono.html向MSVC小组报告了此消息,并且他们确认这是MSVC中的一个错误,已在最新版本的MSVC2017中修复。 Thanks for the discussions!
感谢您的讨论!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.