c++ - enable_if + is_same + constexpr 函数使 MSVC 失败(但在 Clang、GCC 中运行良好)
问题描述
这是一个非常简单的代码:
#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 为 时才启用(在进一步的 SFINAE 情况下)std::array
。是的,我知道我可以做到,template<class T, int N> void test(array<T, N>& v)
但是这个更脏的模板参数在某些情况下可以帮助我没有int N
. (相信我!)
无论如何,此 C++ 17代码无法在具有 C++ 17 设置的 Visual Studio 2019 中编译。但是它在 GCC 和 Clang 中运行良好。
几个小时前,我在这里发布了相关问题。我唯一能发现的共同点是它们是关于一些复杂的模板并且它们会导致相同的错误代码:
error C2672: no matching overloaded function found
error C2783: could not deduce template argument for '__formal'
问题是......
- 那是有效的 C++ 17 代码吗?
- 那么为什么 MSVC 编译失败呢?
- 和我之前的问题有什么关系?
- 如果我决定只使用 MSVC,我应该如何处理?
解决方案
我不知道究竟是什么使 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 中的标准。
推荐阅读
- swagger - 将基于声明的授权策略应用于 .Net Core 3.1 中的 Swagger UI
- google-people-api - 跨域的 gtag 链接器
- python - 如何在嵌套的 while 循环和计数器的帮助下清空字符串并重新生成它
- angular - Angular 中的 AG 网格工具提示
- r - 对来自雅虎的 xts 数据应用延迟不起作用
- node.js - 如果 jwt 使用强算法加密,将 jwt 有效负载存储在 localStorage 中是否安全?
- kubernetes - 每次容器重启时,如何让 Kubernetes 进行一次镜像拉取?
- amazon-web-services - 使用 AWS S3 cli 按年龄修剪文件?
- powershell - 使用 powershell 解压缩嵌套的 zip 文件
- sql - SQL Case 语句逻辑问题