【问题标题】:enable_if + is_same + constexpr function makes MSVC fail (but works well in Clang, GCC)enable_if + is_same + constexpr 函数使 MSVC 失败(但在 Clang、GCC 中运行良好)
【发布时间】: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&lt;class T, int N&gt; void test(array&lt;T, N&gt;&amp; 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'

问题是……

  1. 这是有效的 C++ 17 代码吗?
  2. 那为什么MSVC编译失败?
  3. 和我之前的问题有什么关系?
  4. 如果我决定只使用 MSVC,我应该如何处理?

【问题讨论】:

  • 顺便问一下,你还在用::value::type而不是_ts和_vs是不是有什么特殊原因?
  • @L.F.我知道你在说什么。 但是我可以重载array_size() 并始终选择具有valueV。在我添加其他一些test()s 之后,它就变成了完全典型的 SFINAE 重载解决方案。 (不是硬错误)
  • 对不起,我错了。删除了我之前的评论。
  • @L.F.没关系。 (感谢您对这个问题的兴趣)顺便说一句,_t_v 是什么?
  • 例如,您可以用enable_if_t&lt;xxx&gt; 代替typename enable_if&lt;xxx&gt;::type,用is_same_v&lt;yyy&gt; 代替is_same&lt;yyy&gt;::value

标签: c++ visual-c++ language-lawyer


【解决方案1】:

我不知道究竟是什么使 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 的标准。

【讨论】:

  • 谢谢。我认为 MSVC 在constexpr function call as non-type argument + enable_if_t&lt;&gt;* 的情况下有一些东西@
猜你喜欢
  • 1970-01-01
  • 2022-11-26
  • 2022-10-18
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
相关资源
最近更新 更多