Range-v3 具有ranges::views::drop和 来ranges::views::drop_last从视图的前面或后面删除元素。
它是否提供类似的功能来将元素添加到视图中?
目前,我发现的最短方法是使用 a或 a到concat范围/容器:iotasingle
#include <assert.h>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/concat.hpp>
#include <range/v3/to_container.hpp>
using namespace ranges;
using namespace views;
int main() {
std::vector<int> v{1,2,3};
auto wi = concat(iota(0,1),v);
assert(((wi | to_vector) == std::vector<int>{0,1,2,3}));
auto ws = concat(single(0), v);
assert(((ws | to_vector) == std::vector<int>{0,1,2,3}));
}
Run Code Online (Sandbox Code Playgroud) 我一直std::string_view在一些旧代码中添加 s 来表示配置参数等字符串,因为它提供了只读视图,由于不需要复制,速度更快。
string_view但是,由于operator+未定义,因此无法将两个连接在一起。我看到这个问题有几个答案表明它是一个疏忽,并且有一个建议添加它。但是,这是添加 astring和 a string_view,大概如果实现的话,生成的串联将是std::string
添加两个string_view也属于同一类别吗?如果不是,为什么不string_view支持添加两个?
样本
std::string_view s1{"concate"};
std::string_view s2{"nate"};
std::string_view s3{s1 + s2};
Run Code Online (Sandbox Code Playgroud)
这是错误
error: no match for 'operator+' (operand types are 'std::string_view' {aka 'std::basic_string_view<char>'} and 'std::string_view' {aka 'std::basic_string_view<char>'})
Run Code Online (Sandbox Code Playgroud) 问题在底部以粗体显示。
LYAH 给出了这个使用monaddo符号的例子Writer
import Control.Monad.Writer
logNumber :: Int -> Writer [String] Int
logNumber x = writer (x, ["number " ++ show x])
multWithLog :: Writer [String] Int
multWithLog = do
a <- logNumber 3
b <- logNumber 5
return (x*y)
Run Code Online (Sandbox Code Playgroud)
定义可以在没有do符号的情况下重写:
multWithLog = logNumber 3 >>= (\x ->
logNumber 5 >>= (\y ->
return (x*y)))
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。
之后,书中介绍了tell,并编辑了这样的定义multWithLog:
multWithLog = do
a <- logNumber 3
b <- logNumber 5
tell ["something"]
return …Run Code Online (Sandbox Code Playgroud) 在C++ 中的函数式编程中,第 11 章涉及一些基本的模板元编程。
在这种情况下,作者展示了remove_reference/ 的这种实现remove_reference_t,它与cppreference 中描述的那些实现基本相同。
template<typename T> struct remove_reference { using type = T; };
template<typename T> struct remove_reference<T&> { using type = T; };
template<typename T> struct remove_reference<T&&> { using type = T; };
template<typename T> using remove_reference_t = typename remove_reference<T>::type;
Run Code Online (Sandbox Code Playgroud)
参考上面的代码,作者评论说,在“调用”时remove_reference_t<int>,只有general(或primary?这里的正确词是什么?)模板成功替代T,其他两个失败。这对我来说很清楚,没有办法int可以写成/匹配T&或T&&。
remove_reference_t<int&>然而,关于,作者说第二个专业无法匹配。好吧,由于引用折叠,它不能匹配吗?我的意思是,如果我替换为,则无法T&&匹配,从而得到?int&Tint&int&&& == int&
同样,在调用 时remove_reference_t<int&&>,不能将第一个专业化的T&匹配int&& …
c++ reference template-specialization template-meta-programming c++14
haskell boolean-logic functional-programming category-theory curry-howard
我以为我总是可以放在undefined我还不知道该放什么的同一个地方,并且代码应该可以很好地编译,只有在undefined实际评估时才会在运行时发生错误。
然而,就在这样做时,我开始写一些类似的东西
f = foldl undefined undefined undefined
Run Code Online (Sandbox Code Playgroud)
在文件中,当我尝试加载文件时,GHCi 出现此错误
source.hs:3:7: error:
• Ambiguous type variable ‘t0’ arising from a use of ‘foldl’
prevents the constraint ‘(Foldable t0)’ from being solved.
Probable fix: use a type annotation to specify what ‘t0’ should be.
These potential instances exist:
instance Foldable (Either a) -- Defined in ‘Data.Foldable’
instance Foldable Maybe -- Defined in ‘Data.Foldable’
instance Foldable ((,) a) -- Defined in ‘Data.Foldable’
...plus one other
...plus 29 instances …Run Code Online (Sandbox Code Playgroud) std::transform来自<algorithm>标题的内容适用于范围,它“使”我们能够使用范围作为它们本身的函子(在范畴论的意义上(\xc2\xb9))。std::transform是基于迭代器的,是的,但std::ranges::views::transform不是,并且它的签名与函数语言中相应函数的签名密切匹配(对两个参数的不同顺序取模,但这没什么大不了的)。
当我看到这个问题(以及在回答它的过程中)时,我了解到 C++23 引入了std::optional<T>::transform,它std::optional也创建了一个函子。
所有这些消息确实让我兴奋,但我不禁想到函子是通用的,如果有一个统一的接口就好了transform任何函子都有一个统一的接口会很好,例如 Haskell 中的情况。
这让我认为类似的对象std::ranges::views::transform(具有不同的名称,而不是暗示ranges)可以成为一个定制点,STL不仅可以为范围定制,还可以为std::optionalSTL中的任何其他函子定制,而程序员可以为其用户定义的类定制它。
非常相似,C++23 也引入了std::optional<T>::and_then,它基本上是 的一元绑定std::optional。我不知道有任何类似的函数可以实现范围的单子绑定,但 C++20本质上是withsome_range | std::ranges::views::transform(f) | std::ranges::views::join的单子绑定。some_rangef
这让我认为可能存在一些通用接口,命名它mbind,人们可以选择使用任何类型。例如,STL 将选择std::optional通过按照 来实现它。std::optional<T>::and_then
该语言是否有机会或有计划有一天支持这种通用性?
\n我当然可以看到一些问题。今天 不完全是,破坏依赖于基于 SFINAE 的无效代码检测的代码是可以的。std::ranges::views::transform(some_optional, some_func)无效,因此某些代码可能依赖于 SFINAE。让它突然工作会破坏代码。
(\xc2\xb9) 关于 …
观看时Matt Godbolt 的演讲时时,我惊讶地发现,如果指示 Clang 针对 Haswell\xc2\xb9 架构进行编译,则会得出以下代码
\nint foo(int a) {\n int count = 0;\n while (a) {\n ++count;\n a &= a - 1;\n }\n return count;\n}\nRun Code Online (Sandbox Code Playgroud)\n用于计算设置位int(我不知道我自己需要多长时间才能计算出来),所以它只使用该指令:
foo(int): # @foo(int)\n popcntl %edi, %eax\n retq\nRun Code Online (Sandbox Code Playgroud)\n我想自己尝试一下,但我发现生成的代码是
\nfoo(int): # @foo(int)\n popcntl %edi, %eax\n cmovel %edi, %eax\n retq\nRun Code Online (Sandbox Code Playgroud)\n事实证明,生成的代码在 Clang 10.0.1 和 Clang 11.0.0 之间发生了变化。
\n为什么较新的 Clang 又发出了一条以前不需要的指令?代码是如此简单,以至于我无法理解多一条指令除了使代码变慢之外还能做什么(即使速度可能非常小,我不知道)。
\n\xc2\xb9 作为一个附带问题,事实上不指定-march=haswell会导致更长、更人性化的代码这一事实是否仅仅意味着该选项所针对的物理 CPU 具有用于执行设置位计数和其他操作的电路(好吧,不管 clang 默认是什么)不?
在一个简单的views适配器管道中,调用一个gen函数来生成一系列值(使用内部状态),然后对其进行过滤。
令人惊讶和违反直觉的(至少对我来说)是这样的事实:生成器函数在每次迭代中被调用两次,因此对同一过滤器的下一次检查失败(过滤后的值不会在管道中重用)。
您知道这是否是正确的预期行为(以及为什么)?
libstdc++在 GCC 10.3、11.1 和 trunk(代码)以及range-v3GCC 和 clang(代码)中进行了测试。
int main() {
int n = 0;
auto gen = [&n]() {
auto result = ++n;
std::cout << "Generate [" << result << "]\n";
return result;
};
auto tmp =
ranges::views::iota(0)
| ranges::views::transform([gen](auto &&) { return gen(); })
| ranges::views::filter([](auto &&i) {
std::cout << "#1 " << i << " " << (i % 2) << "\n";
return (i …Run Code Online (Sandbox Code Playgroud) move_constructible我从cppreference得到了以下 C++ 概念的实现
template<typename _Tp>
concept move_constructible =
constructible_from<_Tp, _Tp> &&
convertible_to<_Tp, _Tp>;
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这有效。我认为任何类型都可以转换为自身,因此第二个要求是毫无意义的(上帝,我一定是在某些方面错了)。另外,对于第一个要求,我希望constructible_from<_Tp, _Tp&&>检查类型是否可以从 rvalue-ref 构造(因此移动)。
请解释一下这个实现是如何工作的。
c++ ×7
haskell ×3
c++17 ×2
c++20 ×2
monads ×2
range-v3 ×2
std-ranges ×2
assembly ×1
bitcount ×1
c++-concepts ×1
c++14 ×1
c++23 ×1
clang ×1
constraints ×1
curry-howard ×1
do-notation ×1
functor ×1
reference ×1
rewriting ×1
string-view ×1
typechecking ×1
writer-monad ×1
x86-64 ×1