gpt4 book ai didi

c++ - 类模板特化偏序和函数综合

转载 作者:IT老高 更新时间:2023-10-28 14:00:59 24 4
gpt4 key购买 nike

选择哪个类模板特化是首选的规则包括将特化重写为函数模板,并通过函数模板的排序规则 [temp.class.order] 确定哪个函数模板更特化。考虑这个例子,然后:

#include <iostream>

template <class T> struct voider { using type = void; };
template <class T> using void_t = typename voider<T>::type;

template <class T, class U> struct A { };

template <class T> int foo(A<T, void_t<T>> ) { return 1; }
template <class T> int foo(A<T*, void> ) { return 2; }

int main() {
std::cout << foo(A<int*, void>{});
}

gcc 和 clang 都打印 2这里。这在前面的一些示例中是有意义的 - 对未推断的上下文进行推断( voidvoid_t<T> )只是被忽略了,所以推断 <T, void_t<T>>反对<X*, void>成功但推断 <T*, void>反对<Y, void_t<Y>>两个论点都失败了。很好。

现在考虑这个概括:

#include <iostream>

template <class T> struct voider { using type = void; };
template <class T> using void_t = typename voider<T>::type;

template <int I> struct int_ { static constexpr int value = I; };

template <class T, class U> struct A : int_<0> { };
template <class T> struct A<T, void_t<T>> : int_<1> { };
template <class T> struct A<T*, void> : int_<2> { };

int main() {
std::cout << A<int*, void>::value << '\n';
}

clang 和 gcc 都将此特化报告为模棱两可,介于 1 之间。和 2 .但为什么?合成的函数模板没有歧义。这两种情况有什么区别?

最佳答案

Clang 与 GCC 兼容(并且与依赖于这两种行为的现有代码兼容)。

考虑 [temp.deduct.type]p1:

[...] an attempt is made to find template argument values (a type for a type parameter, a value for a non-type parameter, or a template for a template parameter) that will make P, after substitution of the deduced values (call it the deduced A), compatible with A.

问题的症结在于这里的“兼容”是什么意思。

当对函数模板进行部分排序时,Clang 只是双向推导;如果推演在一个方向上成功但在另一个方向上没有成功,则假设结果将是“兼容的”,并将其用作排序结果。

但是,当对类模板部分特化进行部分排序时,Clang 将“兼容”解释为“相同”的意思。因此,如果将其中一个推导出的参数替换为另一个会重现原始的部分特化,则它只认为一个部分特化比另一个更特化。

更改这两个中的任何一个以匹配另一个会破坏大量实际代码。 :(

关于c++ - 类模板特化偏序和函数综合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42416993/

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