gpt4 book ai didi

c++ - 为什么 Same_as 概念检查类型相等性两次?

转载 作者:行者123 更新时间:2023-12-03 00:14:33 27 4
gpt4 key购买 nike

https://en.cppreference.com/w/cpp/concepts/same_as查看same_as概念的可能实现我注意到发生了一些奇怪的事情。

namespace detail {
template< class T, class U >
concept SameHelper = std::is_same_v<T, U>;
}

template< class T, class U >
concept same_as = detail::SameHelper<T, U> && detail::SameHelper<U, T>;

第一个问题是为什么需要 SameHelper 概念?第二个是为什么 same_as 检查 T 是否与 U 相同以及 U 是否与 T 相同?这不是多余的吗?

最佳答案

有趣的问题。我最近看了 Andrew Sutton 关于 Concepts 的演讲,在问答环节有人问了以下问题(时间戳在以下链接中): CppCon 2018: Andrew Sutton “Concepts in 60: Everything you need to know and nothing you don't”

所以问题归结为:If I have a concept that says A && B && C, another says C && B && A, would those be equivalent? Andrew 回答是,但指出编译器有一些内部方法(对用户透明)将概念分解为原子逻辑命题(atomic constraints 正如 Andrew 所说的术语)并检查它们是否等效。

现在看看 cppreference 关于 std::same_as 的说法。 :

std::same_as<T, U> subsumes std::same_as<U, T> and vice versa.

这基本上是一种“当且仅当”关系:它们相互暗示。 (逻辑等价)

我的猜想是,这里的原子约束是 std::is_same_v<T, U> 。编译器对待 std::is_same_v 的方式可能会让他们思考std::is_same_v<T, U>std::is_same_v<U, T>作为两个不同的约束(它们是不同的实体!)。因此,如果您实现 std::same_as仅使用其中之一:

template< class T, class U >
concept same_as = detail::SameHelper<T, U>;

然后std::same_as<T, U>std::same_as<U, T>会“爆炸”到不同的原子约束并变得不等价。

那么,编译器为什么要关心呢?

考虑this example :

#include <type_traits>
#include <iostream>
#include <concepts>

template< class T, class U >
concept SameHelper = std::is_same_v<T, U>;

template< class T, class U >
concept my_same_as = SameHelper<T, U>;

template< class T, class U> requires my_same_as<U, T>
void foo(T a, U b) {
std::cout << "Not integral" << std::endl;
}

template< class T, class U> requires (my_same_as<T, U> && std::integral<T>)
void foo(T a, U b) {
std::cout << "Integral" << std::endl;
}

int main() {
foo(1, 2);
return 0;
}

理想情况下,my_same_as<T, U> && std::integral<T>包含my_same_as<U, T> ;因此,编译器应该选择第二个模板专门化,除非......它没有:编译器发出错误 error: call of overloaded 'foo(int, int)' is ambiguous .

这背后的原因是因为 my_same_as<U, T>my_same_as<T, U>不互相包含,my_same_as<T, U> && std::integral<T>my_same_as<U, T>变得不可比较(在包含关系下的部分有序约束集上)。

但是,如果你更换

template< class T, class U >
concept my_same_as = SameHelper<T, U>;

template< class T, class U >
concept my_same_as = SameHelper<T, U> && SameHelper<U, T>;

代码编译。

关于c++ - 为什么 Same_as 概念检查类型相等性两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58509147/

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