【发布时间】:2023-03-23 16:13:01
【问题描述】:
这是一个非常简单的代码:
#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 代码无法在 Visual Studio 2019 中使用 C++ 17 设置进行编译。 但是它在 GCC 和 Clang 中运行良好。
几小时前,我发布了相关问题here。 我唯一能找到的共同点是它们是关于一些复杂的模板并且它们会导致相同的错误代码:
error C2672: no matching overloaded function found
error C2783: could not deduce template argument for '__formal'
问题是……
- 这是有效的 C++ 17 代码吗?
- 那为什么MSVC编译失败?
- 和我之前的问题有什么关系?
- 如果我决定只使用 MSVC,我应该如何处理?
【问题讨论】:
-
顺便问一下,你还在用
::value和::type而不是_ts和_vs是不是有什么特殊原因? -
@L.F.我知道你在说什么。 但是我可以重载
array_size()并始终选择具有value的V。在我添加其他一些test()s 之后,它就变成了完全典型的 SFINAE 重载解决方案。 (不是硬错误) -
对不起,我错了。删除了我之前的评论。
-
@L.F.没关系。 (感谢您对这个问题的兴趣)顺便说一句,
_t和_v是什么? -
例如,您可以用
enable_if_t<xxx>代替typename enable_if<xxx>::type,用is_same_v<yyy>代替is_same<yyy>::value。
标签: c++ visual-c++ language-lawyer