提问人:Alan 提问时间:10/16/2023 最后编辑:user3840170Alan 更新时间:10/16/2023 访问量:678
std::enable_if_t 适用于 gcc 和 clang,但不使用 msvc 进行编译
std::enable_if_t works with gcc and clang but does not compile with msvc
问:
我有一个朋友函数模板,它适用于 gcc 和 clang,但不适用于 msvc。operator<<
#include <iostream>
#include <type_traits>
template< typename T, std::enable_if_t< T{1}, int> =0 >
class Foo
{
template< typename Ar, typename R>
friend Ar& operator<<(Ar& os, const Foo<R>& foo)
{
return os;
}
};
int main()
{
Foo<int> i;
std::cout << i; //works with gcc and clang but does not compile with msvc
}
我想知道根据 c++ 标准,哪个编译器具有正确的行为。msvc 错误说:
<source>(4): error C2972: 'Foo': template parameter 'unnamed-parameter': the type of non-type argument is invalid
<source>(6): note: see declaration of 'Foo'
<source>(4): note: the template instantiation context (the oldest one first) is
<source>(11): note: see reference to class template instantiation 'Foo<T,__formal>' being compiled
<source>(15): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'Foo<int,0>' (or there is no acceptable conversion)
答:
14赞
user17732522
10/16/2023
#1
这是一个 MSVC 错误,与 完全无关。operator<<
只要在任何地方提到作为模板参数会导致错误,因为 MSVC 会尝试立即检查 的有效性,即使尚无 / 的具体类型。然后,这将失败。Foo<U>
U
std::enable_if_t< T{1}, int>
U
T
MSVC 无法正确识别这是依赖类型,因此在替换具体 / 之前不应进行检查。std::enable_if_t< T{1}, int>
U
T
有关简化示例,请参阅 https://godbolt.org/z/ncb3va3ro:
template< typename T, std::enable_if_t< T{1}, int> =0 >
class Foo
{
};
template<typename R>
using U = Foo<R>; // <- same error here
评论
1赞
user17732522
10/16/2023
@Alan我不知道。我没有检查 developercommunity.visualstudio.com/home。
6赞
Fedor
10/16/2023
刚刚报道:developercommunity.visualstudio.com/t/......
评论
typename = std::enable_if_t< T{1}>
requires