- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用 C++20 的 concept
s 我注意到 std::unique_ptr
似乎无法满足 std::equality_comparable_with<std::nullptr_t,...>
概念。从 std::unique_ptr
的定义来看,它应该在 C++20 中实现以下内容:
template<class T1, class D1, class T2, class D2>
bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, std::nullptr_t) noexcept;
这个要求应该实现与
nullptr
的对称比较——根据我的理解,这足以满足
equality_comparable_with
。
// fails on all three compilers
static_assert(std::equality_comparable_with<std::unique_ptr<int>,std::nullptr_t>);
Try Online
std::shared_ptr
相同的断言被接受:
// succeeds on all three compilers
static_assert(std::equality_comparable_with<std::shared_ptr<int>,std::nullptr_t>);
Try Online
最佳答案
TL;DR: std::equality_comparable_with<T, U>
要求 T
和 U
都可以转换为 T
和 0x214134 的公共(public)引用。对于 U
和 std::unique_ptr<T>
的情况,这要求 std::nullptr_t
是可复制构造的,而事实并非如此。
系好安全带。这真是一段旅程。考虑我 nerd-sniped 。
为什么我们不满足这个概念?
std::unique_ptr<T>
要求:
template <class T, class U>
concept equality_comparable_with =
std::equality_comparable<T> &&
std::equality_comparable<U> &&
std::common_reference_with<
const std::remove_reference_t<T>&,
const std::remove_reference_t<U>&> &&
std::equality_comparable<
std::common_reference_t<
const std::remove_reference_t<T>&,
const std::remove_reference_t<U>&>> &&
__WeaklyEqualityComparableWith<T, U>;
std::equality_comparable_with
失败
std::equality_comparable_with<std::unique_ptr<int>, std::nullptr_t>
:
<source>:6:20: note: constraints not satisfied
In file included from <source>:1:
/…/concepts:72:13: required for the satisfaction of
'convertible_to<_Tp, typename std::common_reference<_Tp1, _Tp2>::type>'
[with _Tp = const std::unique_ptr<int, std::default_delete<int> >&; _Tp2 = const std::nullptr_t&; _Tp1 = const std::unique_ptr<int, std::default_delete<int> >&]
/…/concepts:72:30: note: the expression 'is_convertible_v<_From, _To>
[with _From = const std::unique_ptr<int, std::default_delete<int> >&; _To = std::unique_ptr<int, std::default_delete<int> >]' evaluated to 'false'
72 | concept convertible_to = is_convertible_v<_From, _To>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
std::common_reference_with<const std::unique_ptr<int>&, const std::nullptr_t&>
要求:
template < class T, class U >
concept common_reference_with =
std::same_as<std::common_reference_t<T, U>, std::common_reference_t<U, T>> &&
std::convertible_to<T, std::common_reference_t<T, U>> &&
std::convertible_to<U, std::common_reference_t<T, U>>;
std::common_reference_with
是
std::common_reference_t<const std::unique_ptr<int>&, const std::nullptr_t&>
(见
compiler explorer link)。
std::unique_ptr<int>
,这相当于要求
std::convertible_to<const std::unique_ptr<int>&, std::unique_ptr<int>>
是可复制构造的。
std::unique_ptr<int>
不是引用?
std::common_reference_t
而不是
std::common_reference_t<const std::unique_ptr<T>&, const std::nullptr_t&> = std::unique_ptr<T>
?两种类型的
const std::unique_ptr<T>&
(
std::common_reference_t
是两个)的文档说:
- If
T1
andT2
are both reference types, and the simple common reference typeS
ofT1
andT2
(as defined below) exists, then themember type type namesS
;- Otherwise, if
std::basic_common_reference<std::remove_cvref_t<T1>, std::remove_cvref_t<T2>, T1Q, T2Q>::type
exists, whereTiQ
is a unaryalias template such thatTiQ<U>
isU
with the addition ofTi
's cv- andreference qualifiers, then the member type type names that type;- Otherwise, if
decltype(false? val<T1>() : val<T2>())
, where val is a function templatetemplate<class T> T val();
, is a valid type, thenthe member type type names that type;- Otherwise, if
std::common_type_t<T1, T2>
is a valid type, then the member type type names that type;- Otherwise, there is no member type.
sizeof...(T)
和
const std::unique_ptr<T>&
没有简单的公共(public)引用类型,因为这些引用不能立即转换为公共(public)基类型(即
const std::nullptr_t&
格式错误)。
false ? crefUPtr : crefNullptrT
没有
std::basic_common_reference
特化。第三个选项也失败了,但我们触发了
std::unique_ptr<T>
。
std::common_type_t<const std::unique_ptr<T>&, const std::nullptr_t&>
、
std::common_type
,因为:
If applying
std::decay
to at least one ofT1
andT2
produces adifferent type, the member type names the same type asstd::common_type<std::decay<T1>::type, std::decay<T2>::type>::type
, ifit exists; if not, there is no member type.
std::common_type<const std::unique_ptr<T>&, const std::nullptr_t&> = std::common_type<std::unique_ptr<T>, std::nullptr_t>
确实存在;它是
std::common_type<std::unique_ptr<T>, std::nullptr_t>
。这就是引用被剥离的原因。
std::unique_ptr<T>
、
std::equality_comparable_with
和
std::totally_ordered_with
以支持仅移动类型。
std::three_way_comparable_with
的公共(public)引用要求是:
[W]hat does it even mean for two values of different types to be equal? The design says that cross-type equality is defined by mapping them to the common (reference) type (this conversion is required to preserve the value).
equality_comparable_with
操作可能天真地期望这个概念是行不通的,因为:
[I]t allows having
t == u
andt2 == u
butt != t2
using common_ref_t = std::common_reference_t<const Lhs&, const Rhs&>;
common_ref_t lhs = lhs_;
common_ref_t rhs = rhs_;
return lhs == rhs;
使用 n3351 支持的 C++0X 概念,如果没有异构
==
,则此实现实际上将用作后备。
operator==(T, U)
存在,所以永远不会使用这个实现。
operator==(T, U)
的公共(public)引用要求太严格了。重要的是,数学要求只是存在一个共同的父类(super class)型,其中这个提升的
std::equality_comparable
是相等的,但是共同的引用要求要求更严格,另外要求:
operator==
获得的父类(super class)型。 std::common_reference_t
提供一个明确的自定义点,您可以在其中明确选择一对类型来满足概念。对于第二点,在数学上,“引用”是没有意义的。因此,第二点也可以放宽,以允许公共(public)父类(super class)型可以从两种类型隐式转换。
std::equality_comparable_with
的
std::common_reference_with
部分来实现:
template <class T, class U>
concept equality_comparable_with =
__WeaklyEqualityComparableWith<T, U> &&
std::equality_comparable<T> &&
std::equality_comparable<U> &&
std::equality_comparable<
std::common_reference_t<
const std::remove_reference_t<T>&,
const std::remove_reference_t<U>&>> &&
__CommonSupertypeWith<T, U>;
template <class T, class U>
concept __CommonSupertypeWith =
std::same_as<
std::common_reference_t<
const std::remove_cvref_t<T>&,
const std::remove_cvref_t<U>&>,
std::common_reference_t<
const std::remove_cvref_t<U>&,
const std::remove_cvref_t<T>&>> &&
(std::convertible_to<const std::remove_cvref_t<T>&,
std::common_reference_t<
const std::remove_cvref_t<T>&,
const std::remove_cvref_t<U>&>> ||
std::convertible_to<std::remove_cvref_t<T>&&,
std::common_reference_t<
const std::remove_cvref_t<T>&,
const std::remove_cvref_t<U>&>>) &&
(std::convertible_to<const std::remove_cvref_t<U>&,
std::common_reference_t<
const std::remove_cvref_t<T>&,
const std::remove_cvref_t<U>&>> ||
std::convertible_to<std::remove_cvref_t<U>&&,
std::common_reference_t<
const std::remove_cvref_t<T>&,
const std::remove_cvref_t<U>&>>);
特别地,该变化是变化到
equality_comparable_with
这个假设
common_reference_with
其中
__CommonSupertypeWith
相差允许
__CommonSupertypeWith
到通过尝试都
std::common_reference_t<T, U>
和
T
创建公共(public)引用产生的
U
或
C(T&&)
并且还引用汽提版本。更多详细信息,请参见
P2404 。
C(const T&)
?
std::equality_comparable_with
(或任何其他
std::equality_comparable_with
概念)的所有使用,有一个谓词重载很有帮助,您可以将函数传递给它。这意味着您可以将
*_with
传递给谓词重载并获得所需的行为(
不是
std::equal_to()
,但不受约束15131313)。
std::ranges::equal_to
是个好主意。
std::equal_to
吗?
std::equality_comparable_with
,其定制点为
std::equality_comparable_with
,目的是:
The class template
basic_common_reference
is a customization point that allows users to influence the result ofcommon_reference
for user-defined types (typically proxy references).
std::common_reference_t
,使我们的类型能够满足
std::basic_common_reference
。另见
How can I tell the compiler that MyCustomType is equality_comparable_with SomeOtherType? 。如果您选择这样做,请注意;
std::basic_common_reference
不仅被
std::equality_comparable_with
或其他
std::common_reference_t
概念使用,你还有可能在 future 导致级联问题。最好确保公共(public)引用实际上是公共(public)引用,例如:
template <typename T>
class custom_vector { ... };
template <typename T>
class custom_vector_ref { ... };
std::equality_comparable_with
可能是
comparison_relation_with
和
custom_vector_ref<T>
之间,甚至可能在
custom_vector<T>
和 0x231414 之间的公共(public)引用的好选择。小心踩踏。
custom_vector_ref<T>
?
custom_vector<T>
专门用于您不拥有的类型(
std::array<T, N>
类型或某些第三方库)在最好的情况下是不好的做法,在最坏的情况下是未定义的行为。最安全的选择是使用您拥有的可以比较的代理类型,或者编写您自己的
std::equality_comparable_with
扩展名,该扩展名具有用于自定义相等拼写的显式自定义点。
std::basic_common_reference
和
std::
之间的等价关系?简单地说,我们改为定义
std::equality_comparable_with
上的等价关系。也就是说,我们取一个共同的父类(super class)型
A
和
B
,并在这个父类(super class)型上定义等价关系。
C = A∪B
必须定义无论身在何处
A
和
B
来的,所以我们必须有
c1 == c2
,
c1
和
c2
(其中
a1 == a2
是
a == b
和
b1 == b2
是
ai
)。转换为 C++,这意味着
A
、
bi
、
B
和
operator==(A, A)
都必须是相同等式的一部分。
operator==(A, B)
/
operator==(B, B)
s 不满足
operator==(C, C)
:而
iterator
可能实际上是某些等价关系的一部分,它既不是等价关系也不是等价关系的一部分,它既不是等价关系,也不是等价关系最后还是两个迭代器都不在最后?”)。
sentinel
,因为你必须记住异构相等不是你正在写的单个
std::equality_comparable_with
,而是四个不同的
operator==(iterator, sentinel)
必须全部一致。
operator==(iterator, iterator)
;为什么我们不能只有
operator==
和
operator==(A, B)
用于优化目的?
operator==
和
operator==
,我们冒着
operator==(C, C)
和
operator==(A, B)
做不同事情的风险。此外,如果我们可以有
operator==(A, B)
,那么这意味着根据我们在
operator==(C, C)
中的内容编写
operator==(A, A)
和
operator==(B, B)
是微不足道的。也就是说,要求
operator==(C, C)
和
operator==(A, A)
的危害是相当低的,作为返回,我们得到了更高的信心,即我们实际上是相等的。
operator==(B, B)
是实际相等吗?无论如何,我永远不会实际使用
operator==(C, C)
或
operator==(A, A)
;我只关心能够进行交叉类型比较。
operator==(B, B)
是实际相等的模型可能会起作用。在这个模型下,我们会有
operator==(A, B)
,但这在所有已知上下文中的确切含义可以敲定。然而,这不是标准的方向是有原因的,在了解是否或如何改变它之前,他们必须首先了解为什么选择标准的模型。
关于c++ - 为什么不的unique_ptr在C++ 20 equality_comparable_with nullptr_t?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66937947/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!