最近我遇到了一个问题,不知何故(但只是某种程度上)对我有意义.它基于解释临时的构造作为单个(!)构造函数参数的声明.请看下面的最小例子.
#include <iostream>
class Foo0{
public:
Foo0(int a){};
void doStuff() {std::cout<<"maap"<<std::endl;};
};
class Foo1{
public:
Foo1(int a){};
void doStuff() {std::cout<<"maap"<<std::endl;};
};
class Foo2{
public:
Foo2(int a){};
void doStuff() {std::cout<<"maap"<<std::endl;};
};
class Bar{
public:
Bar(Foo0 foo0, Foo1 foo1, Foo2 foo2){};
};
int main () {
int x = 1;
Bar bar0(Foo0(x), Foo1(x), Foo2(x)); // Does not work: conflicting declaration ‘Foo1 x’ previous declaration as ‘Foo0 x’; conflicting declaration ‘Foo2 x’ previous declaration as ‘Foo0 x’
Bar bar1(Foo0{x}, Foo1(x), Foo2(x)); // Works …Run Code Online (Sandbox Code Playgroud) 我不清楚抽象语法树的结构.要在AST代表的程序源中"向下(向前)",你是在最顶层的节点上走,还是走下去?例如,是示例程序
a = 1
b = 2
c = 3
d = 4
e = 5
Run Code Online (Sandbox Code Playgroud)
导致AST看起来像这样:

或这个:

在第一个中,在右边的"右边" main node将推进你通过程序,但在第二个中,只需跟随next每个节点上的指针将执行相同的操作.
似乎第二个更正确,因为您不需要像第一个节点那样具有可能极长的指针数组的特殊节点类型.虽然,当你进入for循环和if分支以及更复杂的事情时,我可以看到第二个变得比第一个变得复杂.
language-agnostic construction traversal abstract-syntax-tree
如何就地构造一个可选的聚合?看来我只能构建一个可选的单一事物,而不能构建一个可选的事物集合。
#include <optional>
#include <iostream>
struct Unmovable
{
Unmovable(const Unmovable&) = delete;
Unmovable(Unmovable&&) = delete;
Unmovable& operator=(const Unmovable&) = delete;
Unmovable& operator=(Unmovable&&) = delete;
explicit Unmovable(const char* msg) {
std::cout << msg << '\n';
}
};
struct Things
{
Unmovable one;
Unmovable two;
};
int main(int argc, char* argv[]) {
const bool y = argc > 1 && argv[1][0] == 'y';
std::optional<Unmovable> optionalThing = y
? std::optional<Unmovable>{"works"}
: std::nullopt;
std::optional<Things> optionalThings = y
? std::optional<Things>{
#if ATTEMPT == 1
"jadda", …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习更多关于c ++字符串的知识.
考虑
const char* cstring = "hello";
std::string string(cstring);
Run Code Online (Sandbox Code Playgroud)
和
std::string string("hello");
Run Code Online (Sandbox Code Playgroud)
假设在应用程序的.data部分中存储"hello",然后将字节复制到堆上的另一个区域,由std :: string管理的指针可以访问它们,我是否正确?
我怎么能有效地存储一个非常长的字符串?我正在考虑从套接字流中读取数据的应用程序.我担心连续多次.我可以想象使用链表并遍历此列表.
弦乐已经吓倒了我太久了!
任何链接,提示,解释,进一步的细节,将非常有帮助.
假设我有一个带有一些const引用 成员变量的类,我想禁止某种类型的构造.所以我会声明相应的构造函数是私有的.当然,构造函数必须初始化类的所有const引用 成员变量.但是,这样做会导致奇怪的代码:
class A {
};
class B {
B(const A& a): host(a) {}
private:
B():host(A()) {} // This is ugly and not needed !!
const A& host;
};
Run Code Online (Sandbox Code Playgroud)
是否有另一种方法来禁止某种构造类型,除了声明构造函数是私有的?我不想让编译器为我编写构造函数.
我在使用thread_local时遇到了一些奇怪的行为,并且不确定我是做错了什么还是GCC错误.我有以下最小的repro场景:
#include <iostream>
using namespace std;
struct bar {
struct foo {
foo () {
cerr << "foo" << endl;
}
int i = 42;
};
static thread_local foo FOO;
};
static thread_local bar::foo FREE_FOO;
thread_local bar::foo bar::FOO;
int main() {
bar b;
cerr << "main" << endl;
// cerr << FREE_FOO.i << endl;
cerr << b.FOO.i << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用上面的注释行,输出如下所示:
main
0
Run Code Online (Sandbox Code Playgroud)
随着它取消注释,它变成了这样:
main
foo
foo
42
42
Run Code Online (Sandbox Code Playgroud)
我只是在这里错过了一些愚蠢的东西吗?
$ gcc -v
Using built-in specs. …Run Code Online (Sandbox Code Playgroud) 我有一个容器,它包含一堆指向基类的指针,以及一个接受一些输入并返回一个类的函数,该类是基类的子类.它返回的子类取决于输入.
现在,我有一个像这样的巨型开关语句:
class Base { ... }
class A : public Base { ... }
class B : public Base { ... }
...
class Z : public Base { ... }
Base* depends(int input) {
switch (input) {
case 1:
return new A(...);
case 2:
return new B(...);
...
case 26:
return new Z(...);
default:
...
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更好的方法来设计它.我不知道很多"设计模式"(我认为这就是他们所谓的)所以我不知道是否有一种(明显的)更好的方法来设计它.
c++ inheritance construction class-hierarchy switch-statement
考虑以下C++类:
struct Point
{
int x;
int y;
explicit Point() =default; // 1
explicit Point(int x_, int y_): x(x_), y(y_) { } // 2
};
Run Code Online (Sandbox Code Playgroud)
第二个构造函数用于创建Point具有特定值x和y值的构造函数.第一个存在,以便我可以默认构造一个Point.然而,为了提高效率,这是defaultED和不设置x和y为零.如果我确实想将所有成员设置为零,我可以有另一个构造函数:
explicit Point(int val) : x(val), y(val) { } // 3
Run Code Online (Sandbox Code Playgroud)
这样,我可以选择默认初始化Point,或者将所有成员设置为零来初始化它:
Point p1; // Don't initialize members.
Point p2(0); // Initialize all members to zero.
Run Code Online (Sandbox Code Playgroud)
第三个构造函数的问题是我可以传递任何值,而不仅仅是零.例如:
Point p(1); // Both x and y set to 1! Is this …Run Code Online (Sandbox Code Playgroud) 根据我的理解,以下内容是相同的:
Person p{}; // Case 1
Person p = {}; // Case 1.5
Run Code Online (Sandbox Code Playgroud)
我注意到
Person p = Person{}; // Case 2
Run Code Online (Sandbox Code Playgroud)
产生Case 1与Case 1.5上述及以上相同的跟踪输出。
问题 1:将案例 2 与案例 1 或案例 1.5 进行比较,是因为复制省略还是其他原因?
问题2:以下有什么区别?
Person p{}; // Case 1
Person p = Person{}; // Case 2
Person&& p = Person{}; // Case 3
Run Code Online (Sandbox Code Playgroud) construction ×10
c++ ×9
c++11 ×2
c++17 ×1
constants ×1
gcc4.8 ×1
idioms ×1
inheritance ×1
performance ×1
reflection ×1
stdoptional ×1
string ×1
temporary ×1
thread-local ×1
traversal ×1
zero ×1