- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试模仿 cons-cell
就像函数式编程语言中的列表结构,在 C++ 中使用 constexpr
.我有一个 pair
类型,开始。这是两个不同事物的持有者,但也支持嵌套对。这是代码。
template <typename E1, typename E2>
struct pair {
constexpr pair()
:_car{E1{}}, _cdr{E2{}}
{}
constexpr pair(const E1 &car, const E2 &cdr)
:_car{car}, _cdr{cdr}
{}
constexpr auto car() const{
return _car;
}
constexpr auto cdr() const{
return _cdr;
}
friend std::ostream& operator<<(std::ostream& str,
pair<E1, E2> p){
if(p == pair{})
return str;
str << p.car() << " " << p.cdr();
return str;
}
template <typename Functor>
friend constexpr auto fmap(Functor f,
const pair<E1, E2> p){
if constexpr (std::is_fundamental<E1>::value &&
std::is_fundamental<E2>::value)
return pair{f(p.car()), f(p.cdr())};
else if(std::is_fundamental<E1>::value &&
!std::is_fundamental<E2>::value)
return pair{f(p.car()), fmap(f, p.cdr())};
}
const E1 _car;
const E2 _cdr;
};
template <typename E1, typename E2>
constexpr bool operator==(const pair<E1, E2>& p1, const pair<E1, E2>& p2)
{
return (p1.car() == p2.car()) && (p1.cdr() == p2.cdr());
}
nested_pair
类型。这使我可以更轻松地使用
nested_pair
s .aka 列表。实际列表只是围绕此包装器的 typedef。这是代码。
template <typename Head, typename Tail>
class nested_pair{
public:
constexpr nested_pair():p{}
{}
constexpr nested_pair(Head h, Tail t)
:p{h, t}
{}
constexpr auto prepend(Head h) const{
return nested_pair<Head, decltype(p)>{h, p};
}
constexpr auto head() const {
return p.car();
}
constexpr auto tail() const {
return nested_pair<decltype(p.cdr().car()),
decltype(p.cdr().cdr())>
{p.cdr().car(),
p.cdr().cdr()
};
}
constexpr bool is_empty() const {
return p == pair<decltype(p.car()),
decltype(p.cdr())>
{};
}
template <typename Functor>
friend constexpr auto fmap(Functor f, const nested_pair l) {
const auto res = fmap(f, l.p);
return nested_pair{res.car(), res.cdr()};
}
friend std::ostream& operator<<(std::ostream& str,
nested_pair<Head, Tail> l){
str << l.p;
str << "\n";
return str;
}
private:
const pair<Head, Tail> p;
};
nested_pair
只允许 prepend 因为如果您将列表存储为一对头部和尾部,则 append 需要 O(n) 递归调用。在这里,我将大量工作委托(delegate)给了
pair
和
nested_pair
打包
pair
的构造函数.我相信这些工作正常。我使用以下变量模板将列表定义为嵌套对。
template <typename T>
using list = nested_pair<T, T>;
list
制作
string
类型,如
list<char>
.这应该再次是所有的 constexpr,尽可能多的。我有另一个版本
const char []
构建 constexpr 字符串,但现在我想使用结构递归。这是我失败的尝试。
class lstring{
public:
template <std::size_t N>
constexpr lstring(const char(&cont)[N]) :size{N} {
size_t ind = N - 1;
while(ind >= 0){
content = content.prepend(cont[ind]);
ind--;
}
}
private:
const size_t size;
const list<char> content;
};
char... args
的可变参数模板吗? ?我怎样才能从结构上解开它?我希望能够从像
list<char> s{"hello world"}
这样的字符串文字中初始化它.
最佳答案
你有一个概念问题:
您的 lstring
包含 list<char>
这实际上是一个 nested_pair<char, char>
它又包含一个 pair<char, char>
. 您的字符串始终包含两个 char
s。
字符串类和列表类都需要将它们的长度编码为它们的类型的一部分。 IE。你需要一个 list<char, 5>
获取 5 个列表 char
(因此包含 pair<char, pair<char, pair<char, pair<char, char>>>>
)。否则,您将需要动态内存——这对于编译时常量代码来说是明确的。
现在,进行演示。我希望它能给你一些关于如何实现某些事情的想法。这对我来说也很有趣;) 与您的设计选择相反,我使用了一个特殊的标记值 - nil
- 标记列表的结尾。以下所有代码都在 namespace list
中:
struct nil {
template<typename U>
constexpr auto prepend(U && u) const;
};
nil
(空列表)有一个成员函数模板,可以在前面添加一些东西。它只是声明 - 未定义 - 在这里打破循环依赖。
prepend(mylist, element)
),但我想反射(reflect)您的预期用途(
mylist.prepend(element)
)。
namespace implementation {
template<typename T>
using no_ref_cv = std::remove_cv_t<std::remove_reference_t<T>>;
}
template<typename Car, typename Cdr>
struct cons {
Car car;
Cdr cdr;
template<typename U>
constexpr auto prepend(U && u) const {
using implementation::no_ref_cv;
return cons<no_ref_cv<U>, cons<Car, Cdr>>{std::forward<U>(u), *this};
}
};
prepend
创建一个新的 cons,将新元素作为其第一个元素,并将当前 cons(的拷贝)作为第二个元素。我删除
const
和
volatile
因为否则有点头疼(尝试弄清楚为什么
cons<char, cons<char, cons<const char, cons<char, nil>>>>
不会转换为
cons<char, cons<const char, cons<char, cons<char, nil>>>>
)
nil::prepend
基本上是一样的:
template<typename U>
constexpr auto nil::prepend(U && u) const {
using implementation::no_ref_cv;
return cons<no_ref_cv<U>, nil>{std::forward<U>(u), *this};
}
template<typename Car, typename Cdr>
constexpr auto make_cons(Car && car, Cdr && cdr) {
using implementation::no_ref_cv;
return cons<no_ref_cv<Car>, no_ref_cv<Cdr>>{
std::forward<Car>(car), std::forward<Cdr>(cdr)};
}
How can I unpack this structurally? I want to be able to initialize this from a string literal like
list<char> s{"hello world"}
.
list<char>
不可能(记住——你也需要那里的长度!)。但是
auto s = list::make_list("hello world")
.
CharT (&array)[N]
)并使用该
N
您可以构建具有足够嵌套的类型
cons
保存您的 list :
namespace implementation {
template<typename T, std::size_t N>
struct build_homo_cons_chain {
using type = cons<T, typename build_homo_cons_chain<T, N - 1u>::type>;
};
template<typename T>
struct build_homo_cons_chain<T, 0u> {
using type = nil;
};
}
N == 0
只是一个
nil
(空列表),其他一切都是
cons
带有元素和长度列表
N - 1
.这允许你为你的列表定义正确的类型,你可以使用它来默认初始化它的一个实例,然后循环遍历
car
成员来填补它。像这样的东西:
using list_t = typename implementation::build_homo_cons_chain<char, N>::type;
list_t my_new_list;
// fill my_new_list.car, my_new_list.cdr.car, ... probably with recursion
char
不是问题,但这些都是严格的要求,所以当我们从数组中提供的元素(字符串文字)复制/移动构造列表的元素时,我们会更好:
namespace implementation {
template<std::size_t O, std::size_t C>
struct offset_homo_builder {
template<typename T, std::size_t N>
constexpr auto from( T (&array)[N]) {
return offset_homo_builder<O - 1u, C - 1u>{}.from(array).prepend(array[N - O]);
}
};
template<std::size_t O>
struct offset_homo_builder<O, 0u> {
template<typename T, std::size_t N>
constexpr auto from( T (&array)[N]) {
return nil{};
}
};
}
O
是相对于数组末尾的偏移量,
C
我们仍然需要构建列表的缺点计数。
from
成员函数模板采用长度为
N
的数组并将数组中的元素添加到
N - O
到它递归构建的(较短的)列表。
implementation::offset_homo_builder<3,2>::from("ab")
offset_homo_builder<3,2>::from("ab") --> N = 3, O = 3, C = 2
: cons{'b', nil}.prepend('a') => cons{'a', cons{'b', nil}}
^
|--- offset_homo_builder<2, 1>::from("ab") --> N = 3, O = 2, C = 1
: nil.prepend('b') => cons{'b', nil}
^
|--- offset_homo_builder<1, 0>::from("ab") --> N = 3, O = 1, C = 0 (!specialisation!)
: nil
C
计数很重要,忽略
'\0'
在字符串文字的末尾。所以现在你可以创建一个包含数组所有元素的列表:
template<typename T, std::size_t N>
constexpr auto make_homogenous(T (&array)[N]) {
return implementation::offset_homo_builder<N, N>{}.from(array);
}
template<std::size_t N, typename CharT, typename = typename std::char_traits<CharT>::char_type>
constexpr auto make_string(CharT (& array)[N]) {
static_assert(N > 0, "assuming zero terminated char array!");
return implementation::offset_homo_builder<N, N - 1>{}.from(array);
}
nil
:
template<typename F, typename Car, typename Cdr>
constexpr auto fmap(F functor, cons<Car,Cdr> const & cell) {
return make_cons(functor(cell.car), fmap(functor, cell.cdr));
}
template<typename F>
constexpr auto fmap(F functor, nil const &) {
return nil{};
}
foldl
,
foldr
和 friend 可以类似地实现。您的
operator<<
可以使用
foldl
实现.
namespace list
.
constexpr
:
constexpr char inc(char c) {
return c + 1;
}
static_assert(fmap(inc, list::make_string("ab").prepend('x')).car == 'y', "");
fmap
而不是
list::fmap
.适用于通用代码。
关于c++ - List<Char> 在 C++ 中键入 constexpr 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49741416/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!