相关疑难解决方法(0)

运算符重载的基本规则和习惯用法是什么?

注意:答案是按照特定的顺序给出的,但由于许多用户根据投票而不是给出的时间对答案进行排序,因此这里是答案索引,它们是最有意义的顺序:

(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)

c++ operator-overloading operators c++-faq

2074
推荐指数
8
解决办法
88万
查看次数

未定义的行为和序列点

什么是"序列点"?

未定义的行为和序列点之间的关系是什么?

我经常使用有趣和复杂的表达方式a[++i] = i;,让自己感觉更好.我为什么要停止使用它们?

如果您已阅读此内容,请务必访问后续问题重新加载未定义的行为和序列点.

(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)

c++ c++-faq undefined-behavior sequence-points

970
推荐指数
4
解决办法
10万
查看次数

如何在C++中初始化私有静态成员?

在C++中初始化私有静态数据成员的最佳方法是什么?我在头文件中尝试了这个,但它给了我奇怪的链接器错误:

class foo
{
    private:
        static int i;
};

int foo::i = 0;
Run Code Online (Sandbox Code Playgroud)

我猜这是因为我无法从课外初始化私人成员.那么最好的方法是什么?

c++ initialization static-members

492
推荐指数
11
解决办法
47万
查看次数

返回类型'?:'(三元条件运算符)

为什么第一个返回引用?

int x = 1;
int y = 2;
(x > y ? x : y) = 100;
Run Code Online (Sandbox Code Playgroud)

而第二个不?

int x = 1;
long y = 2;
(x > y ? x : y) = 100;
Run Code Online (Sandbox Code Playgroud)

实际上,第二个根本没有编译 - "没有左边的赋值".

c++ types reference conditional-operator lvalue

207
推荐指数
3
解决办法
2万
查看次数

为什么函数指针定义适用于任意数量的&符号'&'或星号'*'?

为什么以下工作?

void foo() {
    cout << "Foo to you too!\n";
};

int main() {
    void (*p1_foo)() = foo;
    void (*p2_foo)() = *foo;
    void (*p3_foo)() = &foo;
    void (*p4_foo)() = *&foo;
    void (*p5_foo)() = &*foo;
    void (*p6_foo)() = **foo;
    void (*p7_foo)() = **********************foo;

    (*p1_foo)();
    (*p2_foo)();
    (*p3_foo)();
    (*p4_foo)();
    (*p5_foo)();
    (*p6_foo)();
    (*p7_foo)();
}
Run Code Online (Sandbox Code Playgroud)

c c++ function-pointers

204
推荐指数
2
解决办法
1万
查看次数

在C++中通过值传递或通过常量引用传递是否更好?

在C++中通过值传递或通过常量引用传递是否更好?

我想知道哪个是更好的做法.我意识到通过常量引用传递应该在程序中提供更好的性能,因为你没有复制变量.

c++ variables constants pass-by-reference pass-by-value

203
推荐指数
6
解决办法
10万
查看次数

为什么`std :: move`命名为`std :: move`?

C++ 11 std::move(x)函数根本不会移动任何东西.它只是一个转换为r值.为什么这样做?这不是误导吗?

c++ c++-faq rvalue-reference move-semantics c++11

120
推荐指数
2
解决办法
1万
查看次数

std :: move()如何将值传递给RValues?

我发现自己并没有完全理解它的逻辑std::move().

起初,我用谷歌搜索它,但似乎只有关于如何使用的文件std::move(),而不是它的结构如何工作.

我的意思是,我知道模板成员函数是什么,但是当我std::move()在VS2010中查看定义时,它仍然令人困惑.

std :: move()的定义如下.

template<class _Ty> inline
typename tr1::_Remove_reference<_Ty>::_Type&&
    move(_Ty&& _Arg)
    {   // forward _Arg as movable
        return ((typename tr1::_Remove_reference<_Ty>::_Type&&)_Arg);
    }
Run Code Online (Sandbox Code Playgroud)

首先对我来说奇怪的是参数,(_Ty && _Arg),因为当我调用函数时,如下所示,

// main()
Object obj1;
Object obj2 = std::move(obj1);
Run Code Online (Sandbox Code Playgroud)

它基本上等于

// std::move()
_Ty&& _Arg = Obj1;
Run Code Online (Sandbox Code Playgroud)

但正如您已经知道的那样,您不能直接将LValue链接到RValue引用,这让我觉得它应该是这样的.

_Ty&& _Arg = (Object&&)obj1;
Run Code Online (Sandbox Code Playgroud)

但是,这是荒谬的,因为std :: move()必须适用于所有值.

所以我想要完全理解它是如何工作的,我也应该看看这些结构.

template<class _Ty>
struct _Remove_reference
{   // remove reference
    typedef _Ty _Type;
};

template<class _Ty>
struct _Remove_reference<_Ty&>
{   // remove reference
    typedef _Ty _Type;
}; …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics c++11

92
推荐指数
1
解决办法
2万
查看次数

为什么(仅)某些编译器对相同的字符串文字使用相同的地址?

https://godbolt.org/z/cyBiWY

我可以'some'在MSVC生成的汇编代码中看到两个文字,但只有一个有clang和gcc.这导致完全不同的代码执行结果.

static const char *A = "some";
static const char *B = "some";

void f() {
    if (A == B) {
        throw "Hello, string merging!";
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释这些编译输出之间的差异和相似之处吗?为什么即使没有请求优化,clang/gcc也会优化某些内容?这是某种未定义的行为吗?

我还注意到,如果我将声明更改为下面显示的声明,则clang/gcc/msvc根本不会"some"在汇编代码中留下任何声明.为什么行为不同?

static const char A[] = "some";
static const char B[] = "some";
Run Code Online (Sandbox Code Playgroud)

c++ string-literals string-interning language-lawyer

88
推荐指数
3
解决办法
6562
查看次数

pass-by-value和std :: move优于pass-by-reference

我正在学习C++,并试着避免养成坏习惯.根据我的理解,clang-tidy包含许多"最佳实践",我尽可能地尽可能地坚持它们(即使我不一定理解为什么它们被认为是好的),但我不确定我是否了解这里推荐的内容.

我在教程中使用了这个类:

class Creature
{
private:
    std::string m_name;

public:
    Creature(const std::string &name)
            :  m_name{name}
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

这导致了一个讽刺的建议,即我应该通过值而不是引用和使用std::move.如果我这样做,我得到的建议做出name的引用(以确保它不会被复制每次),并警告说std::move将不会有任何影响,因为nameconst这样,我应该将其删除.

我没有得到警告的唯一方法是const完全删除:

Creature(std::string name)
        :  m_name{std::move(name)}
{
}
Run Code Online (Sandbox Code Playgroud)

这似乎是合乎逻辑的,因为唯一的好处const是防止弄乱原始字符串(这不会因为我通过值传递而发生).但我在CPlusPlus.com看到了:

虽然注意到-in标准库移动意味着移动的对象保持有效但未指定的状态.这意味着,在这样的操作之后,移动对象的值应该只被销毁或分配一个新值; 访问它否则会产生一个未指定的值.

现在想象一下这段代码

std::string nameString("Alex");
Creature c(nameString);
Run Code Online (Sandbox Code Playgroud)

因为nameString通过值传递,std::move只会name在构造函数内部无效而不会触及原始字符串.但这有什么好处?看起来无论如何内容只被复制一次 - 如果我在调用时通过引用传递m_name{name},如果我在传递它时传递值(然后它被移动).我知道这比通过值而不是使用std::move(因为它被复制两次)更好.

所以有两个问题:

  1. 我是否正确理解这里发生了什么?
  2. 使用std::move过度引用和调用是否有任何好处m_name{name}

c++

81
推荐指数
2
解决办法
1万
查看次数