gpt4 book ai didi

C++20 概念 : Which template specialization gets chosen when the template argument qualifies for multiple concepts?

转载 作者:行者123 更新时间:2023-12-01 08:52:32 24 4
gpt4 key购买 nike

鉴于:

#include <concepts>
#include <iostream>

template<class T>
struct wrapper;

template<std::signed_integral T>
struct wrapper<T>
{
wrapper() = default;
void print()
{
std::cout << "signed_integral" << std::endl;
}
};

template<std::integral T>
struct wrapper<T>
{
wrapper() = default;
void print()
{
std::cout << "integral" << std::endl;
}
};

int main()
{
wrapper<int> w;
w.print(); // Output : signed_integral
return 0;
}

从上面的代码, int符合两者 std::integralstd::signed_integral概念。

令人惊讶的是,这会在 GCC 和 MSVC 编译器上编译并打印“signed_integral”。我原以为它会失败,并出现“模板特化已经定义”的错误。

好的,这是合法的,足够公平,但为什么 std::signed_integral选择而不是 std::integral ?当多个概念符合模板参数的条件时,标准中是否定义了任何规则来选择模板特化?

最佳答案

这是因为概念可以比其他概念更专业,有点像模板本身的排序方式。这叫做partial ordering of constraints
在概念的情况下,当它们包含等效约束时,它们相互包含。例如,这里是如何 std::integralstd::signed_integral实现:

template<typename T>
concept integral = std::is_integral_v<T>;

template<typename T> // v--------------v---- Using the contraint defined above
concept signed_integral = std::integral<T> && std::is_signed_v<T>;
规范化约束编译器将约束表达式归结为:
template<typename T>
concept integral = std::is_integral_v<T>;

template<typename T>
concept signed_integral = std::is_integral_v<T> && std::is_signed_v<T>;
在本例中, signed_integral暗示 integral完全地。所以从某种意义上说,有符号积分比积分“更受约束”。
标准是这样写的:
来自 [temp.func.order]/2 (强调我的):

Partial ordering selects which of two function templates is morespecialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type.The deduction process determines whether one of the templates is more specialized than the other.If so, the more specialized template is the one chosen by the partial ordering process.If both deductions succeed, the partial ordering selects the more constrained template as described by the rules in [temp.constr.order].


这意味着如果一个模板有多种可能的替代,并且都从偏序中选择,它将选择最受约束的模板。
来自 [temp.constr.order]/1 :

A constraint P subsumes a constraint Q if and only if, for every disjunctive clause Pi in the disjunctive normal form of P, Pi subsumes every conjunctive clause Qj in the conjunctive normal form of Q, where

  • a disjunctive clause Pi subsumes a conjunctive clause Qj if and only if there exists an atomic constraint Pia in Pi for which there exists an atomic constraint Qjb in Qj such that Pia subsumes Qjb, and

  • an atomic constraint A subsumes another atomic constraint B if and only if A and B are identical using the rules described in [temp.constr.atomic].


这描述了编译器用来对约束进行排序的包含算法,以及概念。

关于C++20 概念 : Which template specialization gets chosen when the template argument qualifies for multiple concepts?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59952704/

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