问题标签 [customization-point]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 为什么 std::swap 不使用交换习语?
由于正确使用 std::swap 是:
它有点冗长,但它确保如果 a,b 定义了更好的交换,它就会被选中。
所以现在我的问题是为什么std::swap
不使用这种技术实现所以用户代码只需要调用std::swap
?
所以像这样(noexcept
为了简洁而忽略和限制):
c++ - 为什么我们可以自定义ctors & dtors 但不能自定义访问器?
(这不是关于重载运算符的问题。一般来说。)
我们知道使用 setter 和 getter 方法有很多很好的理由。
那么,我觉得奇怪的是,这些不是成员访问的自定义点,即如果类 A 有一个数据成员 x,那么在左值上下文中使用 x 将不仅仅是使用 x,而是调用一些方法(比如A::get_x_lvalue()
,别管语法)默认为
并且可以实现为覆盖,并且类似地,当在纯右值常量中使用 x 时,将调用可覆盖
...类似于,比如说,你如何在 Javascript 中做到这一点。
我的问题是:
- 从历史上看,为什么没有将它与可定制的复制构造函数、赋值运算符和析构函数一起添加到语言中?
- 有没有正式提出过这样的事情?如果是这样,它的状态是什么或为什么被拒绝?
- 除了: 1. 编译速度较慢和 2. 不能“相信” my_a.x 中的时间段只是普通访问之外,这种方案是否有重大损害?
c++ - 为什么`std::hash`不是通过重载作为`std::begin`的自定义点?
正如标题所说,std::begin
、std::end
、std::swap
等是众所周知的std
“定制点”(旨在由 ADL 找到的功能)。但是,std::hash
我认为,唯一可由用户自定义的 std 行为暗示 (A) 打开std
命名空间 (B) 创建部分专业化。
为什么没有std::hash
像其他的那样通过重载函数而不是部分特化类来设计定制点?
c++ - 类模板名称中的隐藏朋友与内联命名空间中的另一个符号冲突
我想为我的类型提供一个隐藏的朋友,同时在内联命名空间中还有另一个同名的对象。一切都适用于普通类型。
但是如果我有一个模板,当我实例化模板时编译器会出错
这是代码:
较小的例子在这里
顺便说一句,我知道其他技术,例如tag_invoke
但在这里我无法控制名称和库
c++ - 为什么在定义自定义点对象时需要删除函数?
从 libstdc++<concepts>
头文件:
从 MS-STL<concepts>
标头:
我从来没有遇到过= delete;
你想禁止调用复制/移动分配/ctor的上下文。
我很好奇这是否有必要,所以我= delete;
从库中注释掉了这样的部分:
查看以下测试用例是否编译。
它不仅可以编译,而且通过调用 user defined swap
for似乎表现良好struct dummy
。所以我想知道,
template<typename _Tp> void swap(_Tp&, _Tp&) = delete;
在这种情况下究竟做了什么?- 在什么情况下没有
template<typename _Tp> void swap(_Tp&, _Tp&) = delete;
?
c++ - std 类型别名的自定义点
假设我正在lib
命名空间中编写一些通用算法,该算法调用自定义点my_func
。
my_func
第一次尝试是为想要专门针对他的类型的用户使用 ADL my_func
,这是std
类型的别名。当然在他的命名空间中定义它是行不通的,因为 ADL 不适用于别名。std
标准不允许在命名空间中定义它。剩下的唯一选项似乎在算法的命名空间中定义lib
。但是,如果最终用户在包含自定义标头之前包含算法标头,这也不起作用。
第二次尝试是使用 niebloids my_func
,这与 ADL 有相同的问题。
第三次尝试是 using tag_invoke
,它应该与 ADL 有相同的问题,即
- 在用户命名空间中自定义不起作用,因为我的类型是要
std
键入的别名 std
不允许自定义- 命名空间中的自定义
lib
取决于标题包含的顺序 第一点似乎是正确的,但最后一点不是。这似乎有效
为什么这与第一个(原始 ADL)没有相同的问题?
第四次尝试是使用模板专业化,这似乎按预期正常工作
编写通用算法和自定义点并允许客户端自定义 std 类型的别名的最佳方法是什么?
haskell - 如何优雅地处理算法的定制点以及对其参数的约束?
作为示例,让我们采用以下算法来计算两个序列的最长公共子序列,从Rosetta Code复制:
lcs
隐含地假设两个参数都是 type Eq a => [a]
;实际上,如果我尝试明确给出签名lcs :: [a] -> [a] -> [a]
,则会在 where 行发生错误x == y
,而签名lcs :: Eq a => [a] -> [a] -> [a]
有效。
现在假设我有两个列表l1
and l2
,两者都是 type [(a,b)]
,并且我想要它们之间的 LCS,但是在==
定义中使用运算符的方式lcs
仅在snd
每个元素的 s 之间(显然b
需要属于Eq
typeclass) .
我不仅可以提供lcs
这两个列表,还可以提供相等运算符,在上面的具体示例中是(==) `on` snd
. 的签名lcs
将是(a -> a -> Bool) -> [a] -> [a] -> [a]
。
然而,这将迫使用户提供相等运算符,即使是在人们想要使用 plain 的琐碎情况下,并且将参数(==)
包装在 a 中也无济于事。(a -> a)
Maybe
换句话说,我觉得在一般情况下,参数 via 的约束Eq a =>
是可以的,但在其他情况下,可能想要传递一个自定义相等运算符来删除该约束,这使我成为函数重载的事情。
我该怎么办?
c++ - 自定义 BGL 图与拓扑排序一起工作需要什么?
我已经创建了一个自定义 BGL 图模型,就像在这个答案中一样:What is needed to use BGL algorithms on existing data structure ( edges and vertices as vector<Object *>)? .
它采用了一个自定义数据结构,用于一些 Boost.Graph 算法。
链接的答案足以让深度优先搜索工作(Coliru),但我在使用时遇到了问题boost::topological_sort
:
给予:科利鲁
“胶水”层必须满足哪些额外要求才能使用boost::topological_sort
?在内部,拓扑排序使用depth_first_search
,但似乎它可能需要顶点索引图。
c++ - 当其中一个函数实际上是函数对象时,修复或替代 ADL
在下面的代码中,命名空间中的独立组件S
具有自己的定义Big
和Small
类型,以及将其拆分为 s 集合的split
函数。Big
Small
S
还提供了另一个函数 ,work
它利用split
, 并且旨在由其S
自身以及其他依赖组件使用, 例如命名空间中的组件,D
假定它们提供自己的定义Big
和Small
以及它们自己的split
定义将通过 ADL 识别。¹
好吧,实际上S::split
是一个函数对象,而不是一个函数²,
所以 ADL 不起作用。
关于如何解决这些需求的任何建议?
从评论中可以看出,Niebloids 和/或tag_invoke
代表了我的问题的答案。我真的很想更多地了解这些概念。
目前,我对 Niebloids 的理解(我正在阅读Eric Niebler 的这篇博客)是它们是函数对象(当它们在范围内时)阻止 ADL,因此“集中”所有指向不合格自由函数的函数调用与 niebloid 同名;然而,它们operator()
依赖 ADL 将调用转发到适当的自由函数。因此,看起来我的示例代码S::split
中作为函数对象和D::split
作为自由函数之间的对比无法由 niebloids 解决,除非我创建S::split
了一个自由函数(在这种情况下,ADL 在我的简单场景中就足够了)。
¹ 最初是在andwork
中定义的,上面的代码是我尝试的重构,在此期间我遇到了所描述的问题。S
D
² 这样做的原因是,S::split
它在多个上下文中使用S
,它有一些重载operator()
,最重要的是,它经常作为对象传递,非常方便。