小编Bob*_*ane的帖子

使用 CMake 将调试标志从 -g 更改为 -ggdb3

考虑以下简单的 C++ 程序:

// main.cpp
#include <iostream>

int main()
{
    std::cout << "Hello World" << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用 CMake 为该项目生成 Makefile,然后使用 GNU Make 和 g++ 进行构建。我的CMakeLists.txt文件看起来像这样(实际上更复杂,这当然是简化的):

cmake_minimum_required(VERSION 3.20)
project(HelloWorld VERSION 1.0 LANGUAGES CXX)

add_executable(HelloWorld main.cpp)
Run Code Online (Sandbox Code Playgroud)

一切正常,但是在构建调试版本时:

cmake -DCMAKE_BUILD_TYPE=Debug ..
Run Code Online (Sandbox Code Playgroud)

我注意到使用的调试器标志是-g。当运行make VERBOSE=1查看使用了哪些标志时,编译时会显示以下内容main.cpp

[ 50%] Building CXX object CMakeFiles/HelloWorld.dir/main.cpp.o
/usr/bin/c++ -g -MD -MT CMakeFiles/HelloWorld.dir/main.cpp.o -MF CMakeFiles/HelloWorld.dir/main.cpp.o.d -o CMakeFiles/HelloWorld.dir/main.cpp.o -c /home/HelloWorld/main.cpp
Run Code Online (Sandbox Code Playgroud)

请注意-gCMake 自动放置的用于添加调试信息的标志。

我怎样才能将其更改-ggdb3为呢?

c++ gdb cmake

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

C++ API中的渐进式披露

在我阅读Ken Arnold 撰写的文章程序员是人之后,我一直在尝试在最小的C++ API中实现渐进式公开的概念,以了解如何在更大规模上完成它.

渐进式公开是指将API"拆分"为仅在请求时将向API的用户公开的类别的想法.例如,API可以分为两类:基本类别(默认情况下可供用户访问),通常需要和易于使用的方法,以及专家级服务的扩展类别.

我在Web上只找到了一个这样一个实现的例子:db4o库(用Java 编写),但我真的不了解他们的策略.例如,如果我们看一下ObjectServer,它就被声明为一个接口,就像它的扩展类ExtObjectServer一样.然后定义继承自这两个接口的实现ObjectServerImpl类,并在那里实现来自两个接口的所有方法.

这应该允许代码如下:

public void test() throws IOException {
    final String user = "hohohi";
    final String password = "hohoho";
    ObjectServer server = clientServerFixture().server();
    server.grantAccess(user, password);

    ObjectContainer con = openClient(user, password);
    Assert.isNotNull(con);
    con.close();

    server.ext().revokeAccess(user); // How does this limit the scope to 
                                     // expert level methods only since it
                                     // inherits from ObjectServer?

    // ...
});
Run Code Online (Sandbox Code Playgroud)

我对Java的了解并不是那么好,但似乎我误解了这项工作是如何处于更高层次的.

谢谢你的帮助!

c++ api design-patterns

5
推荐指数
1
解决办法
111
查看次数

根据一些枚举值在编译时添加额外的方法

想象一下我有以下课程:

class Extra final
{
public:

    void Method1() const {std::cout << "Method 1" << std::endl;}
    void Method2() const {std::cout << "Method 2" << std::endl;}
};
Run Code Online (Sandbox Code Playgroud)

我为某些类创建了T一个类模板,该模板可以Extra根据不同的场景(在枚举中列出)在编译时启用/禁用方法:

enum class Scenario
{
    None, // No extra.
    One,  // Only Method1 allowed.
    Two,  // Only Method2 allowed.
    Both  // Both Method1 and Method2 allowed.
};
Run Code Online (Sandbox Code Playgroud)

类模板如下所示:

template<typename T, Scenario R>
class ExtraAdder : public T
{
};

template<typename T>
class ExtraAdder<T, Scenario::One> : public T
{
public:

    void Method1Extra() …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-specialization

5
推荐指数
1
解决办法
77
查看次数

隐藏从int到uint8_t的缩小转换

考虑以下代码:

#include <cstdint>

class A
{
public:

    explicit A(uint8_t p_a){ m_a = p_a; };
    uint8_t get_a() const {return m_a;}

private:

    uint8_t m_a;
};

int main()
{
    A a {0x21U};
    A aa{0x55U};

    uint8_t mask{a.get_a() | aa.get_a()};

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译this(gcc 5.4.0)时,我收到以下错误:

main.cpp: In function ‘int main()’:
main.cpp:20:28: warning: narrowing conversion of ‘(int)(a.A::get_a() | aa.A::get_a())’ from ‘int’ to ‘uint8_t {aka unsigned char}’ inside { } [-Wnarrowing]
     uint8_t mask{a.get_a() | aa.get_a()};
Run Code Online (Sandbox Code Playgroud)

我真的不明白为什么会有任何缩小.该int类型从未在我的代码中的任何地方使用过,所有内容都是用unsigned chars语言编写的.即使我明确地转向unsigned char我得到错误:

uint8_t …
Run Code Online (Sandbox Code Playgroud)

c++ type-conversion implicit-conversion narrowing

4
推荐指数
1
解决办法
1788
查看次数

在哪里可以找到有关 Gtkmm 的良好文档?

似乎很难找到有关 Gtkmm 主题的高质量文档。

Gtkmm 有好的文档吗?如果有的话,我在哪里可以找到它?

gtk gtkmm gtk3 gtkmm3

4
推荐指数
1
解决办法
2705
查看次数

std ::绑定到lambda:编译错误

我试图std::bind去一个lambda时遇到了错误.以下代码示例编译正常:

#include <functional>
#include <iostream>

int main()
{
    const auto lambda1 = [](int a, int b){ return a + b; };

    std::cout << (std::bind( lambda1, std::placeholders::_1, 2))(2)
              << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但以下不是:

#include <functional>
#include <iostream>

int main()
{
    const auto lambda2 { [](int a, int b){ return a + b; } }; // Note the "{ }-initialization"

    std::cout << (std::bind( lambda2, std::placeholders::_1, 2))(2)
              << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我使用Visual Studio 2013得到的错误输出,更新4:

1>------ Build started: Project: Project1, …
Run Code Online (Sandbox Code Playgroud)

c++ lambda initializer-list stdbind c++11

3
推荐指数
1
解决办法
73
查看次数

将正确的 doxygen 文档作为构建要求

我正在使用 Doxygen 来记录一个越来越大的 C++ 项目,我一直想知道如何使 Doxygen 成为该项目的构建要求。换句话说,如果有任何类/方法/等,我希望我的构建过程失败并停止。Doxygen尚未成功记录。我用于make建筑。

例如,我希望它失败(即不构建):

/**
 * @bbrief Oops, tag does not exist, warning is issued and hence build fails.
 */
void f()
{
    // Do something...
}


/**
 * @brief Main function for program X
 *
 * @return End of execution status.
 *
 * ...
 *
 */
int main()
{
    f();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但这要构建:

/**
 * @brief Okay, this is fine.
 *
 */
void f()
{
    // Do something...
}


/** …
Run Code Online (Sandbox Code Playgroud)

doxygen

3
推荐指数
1
解决办法
1940
查看次数

在编译时选择随机数分布

我正在使用TYPED_TESTgoogle测试功能编写测试,这使我可以将测试推广到多种类型.我正在测试类型int和类的类模板double.在测试中,我需要生成随机数.为此,我尝试使用std::uniform_int_distribution<T>std::uniform_real_distribution<T>但是遇到了静态断言.

如名称所示,std::uniform_int_distribution<T>检查if T是否为整数类型并std::uniform_real_distribution<T>检查T是否为浮点类型.

由于我的测试自动测试int然后测试double,我一直在尝试编写某种函数,这将允许我在编译时为类型选择正确的类型.更确切地说,类似于:

template<class T>
Distribution get_right_distribution(const T& a, const T& b)
{
    if(T is integral) // Compile time is needed, runtime 
                      // fails since both if and else have to compile
    {
        return std::uniform_real_distribution(a, b);
    }
    else
    {
        return std::uniform_real_distribution(a, b);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这只是我试图做的伪代码.这种逻辑分支失败,因为ifAND else必须编译.

我已经做了一些研究如何做到这一点,我觉得std::is_integral<T>并且std::is_floating_point<T>是解决方案的一部分,但到目前为止我还没有能够编译任何东西.我主要尝试了两件事:

  1. 使用模板专业化创建一种编译时间.
  2. 使用enable_if. …

c++ googletest

3
推荐指数
1
解决办法
193
查看次数

如何在不使用 png 图像的情况下清洁开罗表面区域

这将清洁整个表面:

void surface_clean(Mpaint *mpaint)
{
    mpaint->surface=cairo_image_surface_create_from_png("cxl.cache.png");
}
Run Code Online (Sandbox Code Playgroud)

我只想以、、和cairo_surface_t方式清洁该区域。xywidthheight

有没有这方面的接口?

gtk cairo

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

python 从子进程导入失败

我一直在研究一些 makefile,它们调用一些 python 脚本来执行各种任务。到目前为止,我一直在make安装了 Ubuntu 16.04(64 位)的机器上运行。今天,我尝试使用相同的 makefile 在我的旧 32 位机器上使用 Lubuntu 16.04 进行构建,但在调用 Python 脚本时失败。

起初,我以为我的Python版本不够新,但我也安装了Python 3.5,并且我将python3makefile中的行更改为,但仍然失败:

python3 /home/morane/Documents/Programming/ConnectX/cxPythonTools/RunUnitTests.py -t /home/morane/bin/tests/unit/cxUnitTests.out -l /home/morane/bin/tests/unit/log/unitTests.log
Traceback (most recent call last):
  File "/home/morane/RunUnitTests.py", line 41, in <module>
    from subprocess import CREATE_NEW_CONSOLE
ImportError: cannot import name 'CREATE_NEW_CONSOLE'
Makefile:51: recipe for target 'unittests' failed
make: *** [cxbaseunit] Error
Run Code Online (Sandbox Code Playgroud)

为了测试,我尝试直接在 Python shell 中重复该错误:

Python 3.5.2+ (default, Sep 22 2016, 12:18:14) 
[GCC 6.2.0 20160927] on linux
Type "help", "copyright", "credits" or "license" …
Run Code Online (Sandbox Code Playgroud)

python makefile

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

单元测试私有方法,使它们成为自由函数

在2017年的cppcon视频中,我遇到了Klaus Iglberger的一个名为" Free Your Functions! " 的演讲.在这次演讲中,演讲者谈到了如何切换到自由函数可以简化测试私有方法的过程(参见19:00).这个想法是你将私有方法拉出类(你使它成为一个自由函数),它变得可测试.

起初,我觉得这个想法很有意思,但是我想的越多,我就越不了解这实际上应该如何工作.例如,假设我有以下(虚拟)类:

class SomeClass
{
public:
    SomeClass();
    ~SomeClass();

    void someTask();

private:

    void someComplexTask();
    void someOtherComplexTask();

};

void SomeClass::someTask()
{
    someComplexTask();
    someOtherComplexTask();
}

// private tasks implementations...
Run Code Online (Sandbox Code Playgroud)

然后someComplexTask()someOtherComplexTask()是私有方法.这意味着它们是实现细节,即它们只能在内部SomeClass(或朋友)调用.在我看来,如果你让它们成为自由函数,是的它们变得可测试,但它们不再是私有的,也不仅仅是特定的实现细节SomeClass.实际上,它们可以从代码中的任何地方调用......

所以我的问题是:为什么Iglberger先生的观点有效?

c++ unit-testing private-methods non-member-functions

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

开玩笑 - 类型错误:response.json 不是函数

我们正在对 React-Native 应用程序(使用 Jest)进行单元测试,该应用程序使用fetch.

\n

fetch为了测试它们,我们模拟了 API 调用函数中的调用。到目前为止效果很好。我们还有组合这些 API 调用并对其进行一些逻辑操作的函数。

\n

例如,下面是一个函数,给定令牌后,该函数将获取相关用户的第一个项目 ( project[0]) 并返回该项目中的项目列表。

\n
export async function getAllItems(token) {\n  try {\n    const response = await getCurrentUser(token); // fetch called inside\n    const responseJson = await response.json();\n    const allItemsResp = await getAllItemsFromSpecificProject(\n      token,\n      responseJson.projectIds[0],\n    );                                            // fetch called inside\n    return await allItemsResp.json();\n  } catch (error) {\n    console.log(error);\n    return null;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

函数getCurrentUsergetAllItemsFromSpecificProject都是简单的fetch调用,目前已正确模拟。这是一个尝试测试该getAllItems功能的测试:

\n
it('Gets all items', async () …
Run Code Online (Sandbox Code Playgroud)

javascript json jestjs react-native fetch-api

0
推荐指数
1
解决办法
8613
查看次数