小编Alw*_*ing的帖子

实际使用C++前缀增量运算符返回左值的事实

我刚刚了解到C++中前缀增量运算符的结果是左值.有可能这种行为有助于程序员更有效,但我想不到任何.前缀增量运算符的这种行为有哪些惯用的用法?

c++ c++11

8
推荐指数
2
解决办法
297
查看次数

空括号调用默认构造函数或构造函数采用std :: initializer_list吗?

以下是Effective Modern C++(第55页)的引用:

"假设你使用一组空的大括号来构造一个支持默认构造函数的对象,并且还支持std :: initializer_list构造.你的空括号是什么意思?等规则是你得到默认构造."

我用std :: array尝试过这个:

std::array<int, 10> arr{};
Run Code Online (Sandbox Code Playgroud)

并得到了g ++(版本4.8.2)的警告:

警告:缺少成员'std :: array <int,10ul> :: _ M_elems'的初始值设定项

这是在尝试std::array从空构造一个时得到的警告std::initializer_list(请参阅为什么我可以从{}初始化一个常规数组,而不是std :: array来讨论此警告).

那么,为什么上面的代码行不能解释为调用默认构造函数?

c++ aggregate-initialization c++11

8
推荐指数
1
解决办法
1113
查看次数

理解Alexandrescu关于多重继承的弱点的阐述

更新:我在这里问了一个较窄的问题.

现代C++设计的第6-7页,Andrei Alexandrescu 就构建灵活设计两个C++语言特性(多重继承模板)的优缺点进行了非常基础的讨论.他的结论是:

现在将多重继承的缺点列表与模板的缺点列表进行比较.有趣的是,多重继承和模板促进了互补的权衡.多重遗传有很少的机制; 模板有丰富的机制.多重继承会丢失模板中充斥的类型信息.模板的专业化不能扩展,但多重继承可以很好地扩展.您只能为模板成员函数提供一个默认值,但您可以编写无限数量的基类.

我能感觉到安德烈在这里所说的非常重要,但我无法真正理解所说的内容,没有任何例子来说明这些要点.这个问题要求提供简单的例子来说明这些要点(请继续阅读).

为了使问题更具体,我想请您关注多重继承的弱点.这就是安德烈对他们所说的话(根据对上下文的理解,方括号中的文字是的):

在这样的设置[即多重继承 ],[构建一个灵活的SmartPtr],用户将通过继承一些BaseSmartPtr类和两个类来构建一个多线程,引用计数的智能指针类:MultiThreadedRefCounted.任何经验丰富的班级设计师都知道这种天真的设计不起作用.

分析多重继承无法创建灵活设计的原因,为获得完善的解决方案提供了有趣的思路.使用多重继承来组装单独功能的问题如下:

  1. 力学.没有样板代码以受控方式组装继承的组件.组合BaseSmartPtr,MultiThreaded和RefCounted的唯一工具是一种称为多重继承的语言机制.该语言在组合基类时应用简单的叠加,并建立一组用于访问其成员的简单规则.除最简单的情况外,这是不可接受的.大多数情况下,您需要仔细编排继承类的工作方式以获得所需的行为.
  2. 输入信息.基类没有足够的类型信息来执行其任务.例如,假设您尝试通过从DeepCopy基类派生来为智能指针类实现深层复制.但是DeepCopy有什么接口?它必须创建一个它不知道的类型的对象.
  3. 国家操纵.使用基类实现的各种行为方面必须操纵相同的状态.这意味着它们必须使用虚拟继承来继承保存状态的基类.这使设计复杂化并使其更加严格,因为前提是用户类继承库类,反之亦然.

我非常感谢上面三个项目中的每个项目的简单示例.每个例子都会显示多重继承的一个限制(例如,差的机制)以及模板如何不具备这种限制(Andrei写道" 多重继承模板促进互补权衡").

c++ templates multiple-inheritance policy-based-design

8
推荐指数
0
解决办法
208
查看次数

多态函数调用没有重复代码

假设层次结构的所有类都实现了模板成员函数g.所有类共享两个其他函数的相同实现,f1f2调用此模板:

struct A {
    virtual void f1() {
        g(5);
    }
    virtual void f2() {
        g(5.5);
    }
private:
    template <typename T> void g(T) {std::cout << "In A" << std::endl;}
};

struct B: A {
    // Can I get rid of this duplicate code?
    virtual void f1() {
        g(5);
    }
    virtual void f2() {
        g(5.5);
    }
private:
    template <typename T> void g(T) {std::cout << "In B" << std::endl;}
};

struct C: A {
    // Can I …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism

8
推荐指数
1
解决办法
155
查看次数

为什么不为定义析构函数为= default的类合成移动操作?

编译器不应该为声明析构函数或复制操作(即复制构造函数/赋值)的类合成移动操作的规则是有意义的.毕竟,通过宣布这些操作,该课程承认它需要做一些自定义簿记.

但是,当类将析构函数或复制操作定义为=default?时,这种推理不适用?那么这种情况不应该是规则的例外吗?

编辑:我可能想要将析构函数定义为=default但不是其他特殊操作的一个原因是当我需要基类的虚拟析构函数时,所以我被迫定义一个使其成为虚拟的.

c++ c++11

7
推荐指数
1
解决办法
344
查看次数

通过引用传递数组元素

我正在使用Mono compiler v4.2.1(.NETFramework 4.5)编译以下代码:

Module Module1
    Sub Change(ByRef x As Integer)
        x += 1
    End Sub

    Sub Main()
        Dim arr() As Integer = {1}
        Change(arr(0))
        Console.WriteLine(arr(0))
    End Sub
End Module 
Run Code Online (Sandbox Code Playgroud)

生成的输出是:1.为什么x参数不通过引用绑定到数组元素?有没有办法让这项工作无需传递数组?

其他细节:

  • 我通过HackerRank运行上面的代码

  • 从Visual Studio 2010/2012运行时,上面的代码生成2的输出.

  • 不确定动机是否对问题很重要,但通过引用传递数组元素非常有用.例如,可以实现Swap两个数组元素.

.net vb.net arrays mono pass-by-reference

7
推荐指数
1
解决办法
207
查看次数

为什么 b = (b - x) &amp; x 会得到下一个子集?

竞争性程序员手册》第 99 页建议采用以下方法来遍历集合的所有子集x(集合位代表集合中的数字):

int b = 0;
do {
    // Process subset b
} while (b = (b - x) & x);
Run Code Online (Sandbox Code Playgroud)

我了解有关位表示和按位运算符的所有背景知识。我不明白的是为什么b = (b - x) & x会导致获得下一个子集。 这篇文章给出了一个例子,但没有提供见解。那么,为什么这会起作用呢?

bit-manipulation

7
推荐指数
1
解决办法
196
查看次数

根据作为模板参数的函数的返回值避免分支

假设以下策略类负责算法的一个方面:

struct VoidF {
    static void f() {
        ... // some code that has side effects
    }
};

struct BoolF {
    static bool f() {
        bool res = ...; // some computation
        return res;
    }
};
Run Code Online (Sandbox Code Playgroud)

BoolF政策是"增强感知":当BoolF :: f()的返回true,该算法可以退出.VoidF是"增强 - 不知道",因此它返回void(我不想强迫我的库的用户返回,bool当它对他没有任何意义).

该算法目前编写如下:

template <typename F>
struct Algorithm {
    void run() {
        ... // some computation here

        if (std::is_same<decltype(F::f()), bool>::value) {
            if (F::f()) return;
        } else
            F::f(); // If F is …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

6
推荐指数
1
解决办法
219
查看次数

在组织模式下编写doxygen文档

从1.8.0版开始,doxygen 支持 markdown.对于习惯的人来说org-mode,写入org-mode导出的选择markdown可能很有吸引力.由于markdown实施标准doxygen略有不同markdown,我想问:有没有人尝试过这个工作流程?用这种方式编写文档时应该记住什么?

c++ emacs markdown doxygen org-mode

6
推荐指数
0
解决办法
282
查看次数

默认模板参数的无冲突重新定义

我理解(是一个来源),只要两个定义不冲突,就可以重新定义默认模板参数。因此,我尝试使用 g++ 5.3.1 编译以下内容:

\n\n
template <class = int> class A; // forward declaration\ntemplate <class T = A<>> struct B {};\n\ntemplate <class T = int> class A {}; // "= int" here is for clarity\n\nint main() { return 0; }\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译器抱怨:

\n\n
\n

错误:重新定义 \xe2\x80\x98class T\xe2\x80\x99 的默认参数

\n
\n\n

我的理解哪里不对?

\n

c++

6
推荐指数
1
解决办法
924
查看次数