这是一个非常简单的代码:
#include <tuple>
#include <type_traits>
#include <array>
template <class T> struct TypeHolder {};
template<class T, size_t N>
constexpr size_t array_size(TypeHolder<std::array<T,N>>)
{
return N;
};
using AnyType = int;
template <class V, typename std::enable_if<std::is_same<V,
std::array<typename V::value_type, array_size(TypeHolder<V>())>>::value, AnyType>::type* = nullptr>
void test(V & v)
{
}
int main()
{
std::array<int, 5> x;
test(x);
}
不要问这段代码是干什么用的。没关系这只是我发现的精简示例。重要的是无论如何它似乎都是有效的C ++ 17代码。
test()
仅在V为std::array
时才启用(在进一步的SFINAE情况下)。是的,我知道我可以做template<class T, int N> void test(array<T, N>& v)
,但是这种较脏的模板参数在某些情况下可以帮助我避免int N
。 (相信我!)
无论如何,此C ++ 17 代码无法使用C ++ 17安装程序在Visual Studio 2019中编译。 但是它在GCC和Clang中效果很好。
几小时前,我发布了相关问题here。 我唯一能发现的共同点是它们与一些复杂的模板有关,并且它们导致相同的错误代码:
error C2672: no matching overloaded function found
error C2783: could not deduce template argument for '__formal'
问题是......
答案 0 :(得分:0)
我不知道究竟是什么使MSCV的编译器崩溃,但是用默认类型参数替换默认指针似乎可行:
template <typename V, typename = std::enable_if_t<std::is_same_v<V,
std::array<typename V::value_type, array_size(TypeHolder<V>())>>, AnyType>>
void test(V & v)
两者都应为有效的C ++ 17,因为第二个参数可以从V
中推导出来。也许constexpr函数还不符合MSCV中的标准。