gpt4 book ai didi

c++ - 为什么 Clang 更喜欢主模板而不是 C++17 的特化?

转载 作者:行者123 更新时间:2023-12-03 15:13:42 28 4
gpt4 key购买 nike

以下program从这个 question 中的代码减少:

template <typename T, void (*)(T), typename = void>  
struct S;

template <typename T, void (*f)(T)>
struct S<T, f, void> {};

S<int const, nullptr> s;
在 GCC 的所有版本中,在所有语言版本中, S 的特化当 s 时选择被实例化。
在所有版本的 Clang 中,但仅从 C++17 开始,实例化 s 时会选择主模板。 .
我认为值得注意的一些要点是,如果实例化结束 <int, nullptr>,则永远不会选择主节点。 ,即第一个参数不再是 int const .此外,如果第二个参数中的函数指针签名不包含 T,则永远不会选择主函数。作为参数,即如果第二个参数是 T (*)() , 或 void (*)() , 说。
如果此代码不是 IFNDR,那么哪个编译器是正确的? C++17 语言修订版中是否有一些重大变化?

最佳答案

这是因为 C++17 允许从非类型参数的类型推导出模板类型参数。 [temp.deduct.type]/13 :

When the value of the argument corresponding to a non-type templateparameter P that is declared with a dependent type is deduced froman expression, the template parameters in the type of P are deducedfrom the type of the value.


所以当我们尝试匹配 S<int const, nullptr>针对偏特化,我们推导出偏特化的模板参数 T来自两个来源:
  • 从第一个模板参数 int const ,我们推导出 T = int const
  • 从第二个模板参数(类型为 void (*)(int) 因为函数参数的顶级 cv 限定被调整掉),我们推导出 T = int .

  • 由于我们推导了相互矛盾的结果,推导失败,部分特化不匹配。
    类似的例子早在 2019 年就出现在核心反射器上。 有一些共识认为这是标准中的一个缺陷,并且从非类型模板参数的类型推导应该只发生在其他不可推导的事情上。

    关于c++ - 为什么 Clang 更喜欢主模板而不是 C++17 的特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66740897/

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