gpt4 book ai didi

c++ - clang/gcc 类特化不一致

转载 作者:行者123 更新时间:2023-12-03 02:13:08 24 4
gpt4 key购买 nike

我在尝试将 tuple_size/tuple_element 专门用于 C++17 中的自定义类以进行结构化绑定(bind)时遇到了此问题。

下面的代码可以在 GCC 中编译,但不能在 clang 中编译(两个 trunk 版本,请参阅下面的链接)。

#include <type_traits>

template<typename T, typename... Ts>
using sfinae_t = T;

template<typename T, bool... Bs>
using sfinae_v_t = sfinae_t<T, typename std::enable_if<Bs>::type...>;

template <typename T>
struct Test;

template <typename T>
struct Test<sfinae_v_t<T, std::is_integral_v<T>>> {};

void f() {
Test<int> t;
}

https://godbolt.org/z/ztuRSq

这是clang提供的错误:

<source>:13:8: error: class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list

struct Test<sfinae_v_t<T, std::is_integral<T>::value>> {};

^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1 error generated.

Compiler returned: 1

这是编译器中的错误还是上面的代码调用了某些 UB?

最佳答案

我在下面(在旧帖子下)所说的在一定程度上应该是正确的,但实际的问题是,SFINAE 被错误地使用,因此我不再确定这是海湾合作委员会的一个错误。

别名声明必须始终成功,您不能在那里 SFINAE,因为它不是类或函数声明或特化(这是有道理的,因为您不能特化别名)。如果别名声明不成功,则程序格式错误。因此,编译器可能会认为,在您强制实例化这样的模板之前,它永远不会出现别名声明不成功的情况。

因此,编译器认为sfinae_v_t<T,...>是完全可以接受的。总是T ,因为当程序没有格式错误时就会发生这种情况。因此,它将看到,在程序不是格式错误的所有情况下,部分特化不会特化,因此它会告诉您这是格式错误的。 (这就是 clang 所做的)。

我不认为编译器被迫这样做。如果没有,并且只是认为“好吧,sfinae_v_t 是某种类型,无论如何。”,那么这是一个重新声明并不明显。所以我认为在我们实例化其中一个之前,不抛出错误没有什么问题。

但是当我们实例化它时,应该会出现我们重新声明的问题或者由于 std::enable_if 导致程序格式不正确的问题。 ,取决于模板参数。 GCC 应该至少选择其中之一,但两者都没有。

这也绝对不适用于没有 std::enable_if 的更简单的示例。 。所以我仍然认为这是 GCC 中的一个错误,但我已经够心烦意乱了,我不能再肯定地说这一点了。我只是想说,应该有人将其报告为错误,并让海湾合作委员会的人员考虑一下。

旧帖子

这是 gcc 中的一个错误。标准给了我们rules用于转换函数模板中的类模板。如果一个类模板的函数在部分函数模板排序中位于另一个类模板之前,则该类模板比另一个类模板更专业。

我创建了函数 here现在 gcc 声称调用它们是不明确的,因此它还必须说类模板是同等指定的。

注意:仔细阅读标准,我脑子里的编译器同意clang。

关于c++ - clang/gcc 类特化不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59756201/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com