能够在C++编译时创建和操作字符串有几个有用的应用程序.尽管可以在C++中创建编译时字符串,但是该过程非常麻烦,因为字符串需要声明为可变字符序列,例如
using str = sequence<'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!'>;
Run Code Online (Sandbox Code Playgroud)
诸如字符串连接,子字符串提取等许多操作可以很容易地实现为对字符序列的操作.是否可以更方便地声明编译时字符串?如果没有,是否有一个提案可以方便地声明编译时字符串?
理想情况下,我们希望能够如下声明编译时字符串:
// Approach 1
using str1 = sequence<"Hello, world!">;
Run Code Online (Sandbox Code Playgroud)
或者,使用用户定义的文字,
// Approach 2
constexpr auto str2 = "Hello, world!"_s;
Run Code Online (Sandbox Code Playgroud)
哪里decltype(str2)有一个constexpr构造函数.方法1的混乱版本可以实现,利用您可以执行以下操作的事实:
template <unsigned Size, const char Array[Size]>
struct foo;
Run Code Online (Sandbox Code Playgroud)
但是,数组需要有外部链接,所以要使方法1起作用,我们必须编写如下内容:
/* Implementation of array to sequence goes here. */
constexpr const char str[] = "Hello, world!";
int main()
{
using s = string<13, str>;
return 0; …Run Code Online (Sandbox Code Playgroud) 我一直在constexpr研究C++ 的新功能,但我并不完全理解它的必要性.
例如,以下代码:
constexpr int MaxSize()
{
...
return ...;
}
void foo()
{
int vec[MaxSize()];
}
Run Code Online (Sandbox Code Playgroud)
可以替换为:
int MaxSize()
{
...
return ...;
}
static const int s_maxSize = MaxSize();
foo()
{
int vec[s_maxSize];
}
Run Code Online (Sandbox Code Playgroud)
更新
第二个例子实际上不是标准的ISO C++(感谢几个用户指出这一点),但某些编译器(例如gcc)支持它.因此,这不是const使程序有效,而是gcc支持这种非标准功能的事实.(据我所知,只有当数组被定义为函数或方法的本地数据时才有可能,因为在编译时必须知道全局数组的大小.)如果我编译没有选项-std=c++98 -pedantic-errors,甚至代码
int MaxSize()
{
return 10;
}
void foo()
{
int vec[MaxSize()];
}
Run Code Online (Sandbox Code Playgroud)
将使用gcc编译.
因此,考虑到目前为止的反馈(以及我在同一时间进行的一些进一步阅读),我将尝试重新解释我的问题.
我const大量使用关键字.随着const我可以定义有其整个生命周期内某一特定值的常数.可以使用任何表达式初始化常量,该表达式被计算一次,即创建常量时.对于这些情况,我认为这constexpr是非常无用的:它将引入一个非常小的优化,因为定义常量值的表达式将在编译时而不是运行时计算.每次我需要一个复杂初始化的运行时常量时我都会使用关键字const.
因此constexpr,在我们需要在编译时初始化常量的情况下,可能会派上用场.一个示例是矢量定义:标准不支持在运行时定义大小.另一个示例是具有一个或多个非类型参数的模板.
在这种情况下,我通常使用宏:
#define MAX_SIZE (10)
void foo()
{
int …Run Code Online (Sandbox Code Playgroud) 我们每个人(可能)都有童年的写作梦想:
switch(my_std_string) {
case "foo": do_stuff(); break;
case "bar": do_other_stuff(); break;
default: just_give_up();
}
Run Code Online (Sandbox Code Playgroud)
但这是不可能的,正如古代(2009年)对这个问题的答案所解释的那样:
从那时起,我们已经看到了C++ 11的出现,它让我们走得更远:
switch (my_hash::hash(my_std_string)) {
case "foo"_hash: do_stuff(); break;
case "bar"_hash: do_other_stuff(); break;
default: just_give_up();
}
Run Code Online (Sandbox Code Playgroud)
如在描述答案来编译时间字符串哈希 -这是没有那么糟糕,但它实际上并没有做正是我们想要的-有碰撞的机会.
我的问题是:从那时起语言的发展(我认为主要是C++ 14)是否影响了编写一个字符串case语句的方式?或简化实现上述目的的螺母和螺栓?
具体而言,与结束C++ 17标准之中指日可待 -我很感兴趣,鉴于我们可以假设标准将包含答案.
注意:这不是关于使用switch语句的优点的讨论,也不是关于meta的线程的讨论.我问的是一个内容丰富的问题,所以请在此基础上回答/ up/downvote.
前段时间,我为c和c ++程序制作了这个漂亮的断言宏
#define ASSERT(truthy, message) \
if (!(truthy)) \
{\
cout << message << " on line " << __LINE__ << " in file " << __FILE__ << ". Check was " << #truthy << endl;\
}
Run Code Online (Sandbox Code Playgroud)
Scatter ASSERT调用整个代码,只要truthy值不真实,它就会发出警告!在开发过程中非常方便,以提醒您潜在的错误.
前
ASSERT(filesFound > 0, "Couldn't find any files, check your path!");
Run Code Online (Sandbox Code Playgroud)
当filesFound为0时,宏将打印出来
找不到任何文件,检查你的路径!在文件openFiles.c的第27行.检查是filesFound> 0
现在,我希望它打印,给我更多相关信息,是传递给truthy参数的任何变量的值.像这样
找不到任何文件,检查你的路径!在文件openFiles.c的第27行.检查是filesFound> 0,filesFound是0
我想知道,这似乎是类似lisp的领域,是否有任何黑魔法预处理可用于评估变量和函数的值,而无需评估truthy语句?
我假设很失望.
为什么这个程序在C++中编译好而不是在C++中的答案?解释说,与C语言不同,C++语言不允许char数组的初始化字符串不足以容纳终止空字符.有没有办法char在C++中指定一个未终止的数组,而不会在源代码中将字符串膨胀四倍?
例如,在C和C++中,以下内容是等效的:
const char s[] = "Hello from Stack Overflow";
const char s[] = {'H','e','l','l','o',' ','f','r','o','m',' ','S','t','a','c','k',' ','O','v','e','r','f','l','o','w','\0'};
Run Code Online (Sandbox Code Playgroud)
因为字符串的"Hello from Stack Overflow"长度为25,所以它们会产生一个26个元素的char数组,就像下面的代码一样:
const char s[26] = "Hello from Stack Overflow";
const char s[26] = {'H','e','l','l','o',' ','f','r','o','m',' ','S','t','a','c','k',' ','O','v','e','r','f','l','o','w','\0'};
Run Code Online (Sandbox Code Playgroud)
仅在C中,程序可以排除终止空字符,例如字符串的长度是否在带外已知.(在C99标准的第6.7.9章中查找"如果有空间,则包括终止空字符".)
const char s[25] = "Hello from Stack Overflow";
const char s[25] = {'H','e','l','l','o',' ','f','r','o','m',' ','S','t','a','c','k',' ','O','v','e','r','f','l','o','w'};
Run Code Online (Sandbox Code Playgroud)
但在C++中,只有第二个是有效的.如果我知道我将使用系列中的函数来操作数据std::strn,而不是std::str系列函数,那么C++语言中是否有与C的简写语法相对应的?