小编Geo*_* P.的帖子

C++连接多态对象的容器

假设我有一个虚拟基类和一些派生的具体类:

class Base { ... }
class DerivedA : public Base { ... }
class DerivedB : public Base { ... }
class DerivedC : public Base { ... }
Run Code Online (Sandbox Code Playgroud)

在某些地方,我有每个派生类的对象向量:

std::vector<DerivedA> my_a;
std::vector<DerivedB> my_b;
std::vector<DerivedC> my_c;
Run Code Online (Sandbox Code Playgroud)

现在,我经常需要迭代所有三个向量中的所有元素并运用基类接口.我可以编写三个for循环,每个循环完全相同.但显然这远非最佳解决方案.

有没有一种聪明的方法将向量连接到具有基类指针/引用的公共容器中,这样我只需要迭代一次?或任何其他想法如何优雅地解决这个问题?

c++ polymorphism containers c++11

15
推荐指数
2
解决办法
789
查看次数

C++将std :: function对象传递给variadic模板

我想将一个可调用的(std::function对象)传递给一个类Foo.callable指的是具有任意参数的另一个类的成员方法,因此Foo必须是可变参数模板.考虑以下代码:

struct Bar {
  void MemberFunction(int x) {}
};

template<typename ...Args>
class Foo {
 public:
  Foo(std::function<void(Bar*, Args...)> f) {}
};

int main() {
  Foo<int> m1(&Bar::MemberFunction);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译好了.现在我想写一个工厂函数MakeFoo()返回一个unique_ptr到一个Foo对象:

template<typename ...Args>
std::unique_ptr<Foo<Args...>> MakeFoo(std::function<void(Bar*, Args...)> f) {
  return std::make_unique<Foo<Args...>>(f);
}
Run Code Online (Sandbox Code Playgroud)

通过调用使用此功能

auto m2 = MakeFoo<int>(&Bar::MemberFunction);
Run Code Online (Sandbox Code Playgroud)

在main中,给出了以下编译器错误:

functional.cc: In function ‘int main()’:
functional.cc:21:50: error: no matching function for call to ‘MakeFoo(void (Bar::*)(int))’
       auto m2 = MakeFoo<int>(&Bar::MemberFunction);
                                                  ^
functional.cc:15:35: note: candidate: …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-templates c++11

10
推荐指数
1
解决办法
743
查看次数

CMake:为每个项目设置编译选项和编译功能

我有一个包含多个软件组件(可执行文件、库)的代码库(例如存储库)。所有内容都是使用 CMake 构建的,每个组件都有单独的目标。

现在,我知道设置编译器标志的现代方法是特定于目标的:

target_compile_options(foo PRIVATE -Werror -Wall -Wextra -pedantic)
target_compile_features(foo PRIVATE cxx_std_17)
Run Code Online (Sandbox Code Playgroud)

但是,我希望整个项目中的所有目标都具有相同的标志。为每个目标编写这些行会导致代码重复并且容易出错(尤其是当标志数量增加时)。有没有某种方法可以将编译器标志附加到项目而不是目标?

我知道我可以向顶级目录添加选项,如下所示:

add_compile_options(-Werror -Wall -Wextra -pedantic)
Run Code Online (Sandbox Code Playgroud)

但我不确定这是否是正确的方法,而且我也不确定如何对编译功能执行相同的操作(cxx_std_17)。

cmake

9
推荐指数
1
解决办法
5371
查看次数

带有cmake工具链文件的Yocto SDK

我提供了一个Yocto SDK来为嵌入式目标交叉构建应用程序.应用程序本身是使用CMake构建的.SDK安装脚本提供了许多必要的环境变量(如交叉编译器的位置,sysroot等),到目前为止,它足以构建应用程序.

但是,最近应用程序依赖于Boost库(通过find_package(Boost REQUIRED)CMakeLists.txt中的命令).现在,CMake抱怨它无法找到库,即使它已安装在SDK sysroot中.但是,如果我直接在Yocto中构建应用程序,它可以正常工作.

经过一些研究后发现,Yocto生成了一个toolchain.cmake添加到cmake调用的文件.在此文件中,CMAKE_FIND_ROOT_PATH设置了变量,CMake需要查找库.使用这样的工具链文件,我也可以使用SDK构建.

现在我想知道Yocto是否提供了使用SDK导出这样一个工具链文件的任何机制.或者,如果SDK提供了一个脚本或其他东西,可以直接在SDK构建主机上自动创建工具链文件.

或者我应该告诉SDK的用户手动创建工具链文件并将其添加到他们的cmake调用?

sdk cmake toolchain yocto

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

Google Mock:可以使用全局模拟对象吗?

在有关gmock 的所有文档中,我总是发现要在测试中实例化的模拟对象,如下所示:

TEST(Bim, Bam)
{
    MyMockClass myMockObj;
    EXPECT_CALL(MyMockObj, foo(_));
    ...
}
Run Code Online (Sandbox Code Playgroud)

因此,每次测试都会创建和销毁对象。我相信创建和销毁每个测试装置的对象也完全没问题。但我想知道是否也可以拥有模拟对象的文件全局实例,如下所示:

MyMockClass myMockObj;

TEST(Bim, Bam)
{
    EXPECT_CALL(MyMockObj, foo(_))
    ...
}
Run Code Online (Sandbox Code Playgroud)

我试过了,到目前为止我绝对没有问题,它似乎一切正常。但也许我应该知道什么?只是因为我偶然发现了这个问题,唯一的答案是:

...问题在于您正在实例化 FooMock 的全局实例。Googlemock/googletest 期望在测试主体内或测试夹具类内定义模拟。

但是我在文档或其他任何地方都找不到任何证实这一点的内容(我是否忽略了它?)。

谢谢,乔治

PS:我需要使用全局模拟实例的原因将是另一个讨论的主题(请参阅我的这篇帖子)。

c++ unit-testing mocking googletest gmock

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

cpplint.py &amp; cmake:如何指定包含文件

假设我有一个目录结构如下的项目:

myproject
??? .git [...]
??? CMakeLists.txt
??? src
    ??? CMakeLists.txt
    ??? foo.cc
    ??? foo.h
Run Code Online (Sandbox Code Playgroud)

如果在src/foo.cc我包含头文件#include "foo.h",然后在其上运行 Google 的cpplint.py,它会抱怨

src/foo.cc:8:  Include the directory when naming .h files  [build/include] [4]
Run Code Online (Sandbox Code Playgroud)

所以我把它作为#include "./foo.h". 现在我收到另一个投诉:

src/foo.cc:8:  src/foo.cc should include its header file src/foo.h  [build/include] [5]
Run Code Online (Sandbox Code Playgroud)

但是,如果我将它包含为#include "src/foo.h",编译器将找不到它,因为我当前的 CMake 设置。这是我的两个 CMakeLists.txt 文件的样子:

CMakeLists.txt:

project(myproject)
add_subdirectory(src)
Run Code Online (Sandbox Code Playgroud)

源代码/CMakeLists.txt:

set(SRCS foo.cc)
add_executable(foo ${SRCS})
Run Code Online (Sandbox Code Playgroud)

我使用 CMake 的方式在某种程度上从根本上是错误的吗?我应该src/CMakeLists.txt完全删除文件,并使用CMakeLists.txt完整路径指定基础中的所有源文件吗?

或者我应该简单地忽略 cpplint 的抱怨,因为它们并不真正适合 CMake 项目的设置方式?

c++ cmake include-path cpplint

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

Docker:高效地将映像迁移到另一个注册表

我需要将许多 Docker 映像从旧注册表迁移到新注册表。执行此操作的标准方法是:

docker pull old-registry/image:tag
docker tag old-registry/image:tag new-registry/image:tag
docker push new-registry/image:tag
docker rmi old-registry/image:tag
docker rmi new-registry/image:tag
Run Code Online (Sandbox Code Playgroud)

现在,其中一些图像非常巨大,超过100GB,并且整个过程需要很长时间。谁能想出一种方法来加快速度吗?是否有类似注册中心之间直接转移的方式?或者,至少有可能避免docker pull命令上的“提取阶段”。因为这里的提取比拉取花费的时间要长得多,而且我实际上并不需要提取它。

docker docker-registry

5
推荐指数
0
解决办法
186
查看次数

CTest 在子目录中添加测试

我有一个基于 CMake 的项目,它由几个子组件组成,这些子组件都可以独立编译和测试。目录布局如下所示:

.
??? CMakeLists.txt
??? comp1
?   ??? CMakeLists.txt
?   ??? src
?   ?   ??? foo.cc
?   ?   ??? foo.h
?   ??? tests
?       ??? CMakeLists.txt
?       ??? test_comp1.cc
??? comp2
    ??? CMakeLists.txt
    ??? src
    ?   ??? bar.cc
    ?   ??? bar.h
    ??? tests
        ??? CMakeLists.txt
        ??? test_comp2.cc
Run Code Online (Sandbox Code Playgroud)

我想启用 ctest,因此在我拥有的根 CMakeLists.txtinclude(CTest)和我拥有的特定于组件的 CMakeLists.txt 文件中

if(BUILD_TESTING)
  add_subdirectory(tests)
endif()
Run Code Online (Sandbox Code Playgroud)

在 compX/tests/CMakeLists.txt 我有编译测试和add_test()命令的代码。测试成功编译,我可以手动运行它们。但是,如果我打电话ctest,它会返回

No tests were found!!!
Run Code Online (Sandbox Code Playgroud)

在玩了一会儿之后,事实证明,如果我add_subdirectory(tests)像这样将调用移动到根 CMakeLists.txt:

if(BUILD_TESTING)
  add_subdirectory(comp1/tests)
endif()
Run Code Online (Sandbox Code Playgroud)

有用。但是我发现将特定于组件的内容放入根文件中非常丑陋和混乱。

相反,我尝试将include(CTest) …

cmake ctest

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

Bitbake:强制执行一个配方任务,然后执行所有操作

我想强制重新编译一个包,就像那样:

bitbake -f -c compile mypackage
Run Code Online (Sandbox Code Playgroud)

不过,我也希望被执行的所有以下任务(如install,package等),就像我曾呼吁bitbake mypackage从一个完全干净的状态.这可以在完成一个步骤,而不是下面的两个?

bitbake -f -c compile mypackage
bitbake mypackage
Run Code Online (Sandbox Code Playgroud)

或者作为替代解决方案,我可以以某种方式"污染"编译任务,以便bitbake mypackage从编译开始执行所有操作吗?

openembedded bitbake yocto

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

为什么 Docker 入口点脚本不在分离模式下执行?

假设这个简单的 Dockerfile:

FROM debian:stretch
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod a+x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
Run Code Online (Sandbox Code Playgroud)

entrypoint.sh 看起来像这样:

#!/bin/bash
echo yyyyyyyyyyyyyyy
exec "$@"
Run Code Online (Sandbox Code Playgroud)

现在,如果我构建映像并在前台创建容器,则会执行入口点脚本:

$ docker build . -t mytest
[...]
$ docker run --rm -it mytest /bin/bash
yyyyyyyyyyyyyyy
root@3e3d7290b09c:/#
Run Code Online (Sandbox Code Playgroud)

但是如果我在分离模式下创建容器,它不会被执行:

$ docker run --rm -d -it mytest /bin/bash
f8e72a222c5194f61843569ae76798bb09736fa4205b93e484f11de32df4db64
Run Code Online (Sandbox Code Playgroud)

这是为什么?或者,更重要的是,我如何创建一个分离的容器,在其中执行入口点脚本?

docker

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